diff options
456 files changed, 11512 insertions, 5519 deletions
diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl index 8bca1d5cec09..e8473eae2a20 100644 --- a/Documentation/DocBook/tracepoint.tmpl +++ b/Documentation/DocBook/tracepoint.tmpl | |||
@@ -16,6 +16,15 @@ | |||
16 | </address> | 16 | </address> |
17 | </affiliation> | 17 | </affiliation> |
18 | </author> | 18 | </author> |
19 | <author> | ||
20 | <firstname>William</firstname> | ||
21 | <surname>Cohen</surname> | ||
22 | <affiliation> | ||
23 | <address> | ||
24 | <email>wcohen@redhat.com</email> | ||
25 | </address> | ||
26 | </affiliation> | ||
27 | </author> | ||
19 | </authorgroup> | 28 | </authorgroup> |
20 | 29 | ||
21 | <legalnotice> | 30 | <legalnotice> |
@@ -91,4 +100,8 @@ | |||
91 | !Iinclude/trace/events/signal.h | 100 | !Iinclude/trace/events/signal.h |
92 | </chapter> | 101 | </chapter> |
93 | 102 | ||
103 | <chapter id="block"> | ||
104 | <title>Block IO</title> | ||
105 | !Iinclude/trace/events/block.h | ||
106 | </chapter> | ||
94 | </book> | 107 | </book> |
diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt index a6d32e65d222..a8536cb88091 100644 --- a/Documentation/RCU/NMI-RCU.txt +++ b/Documentation/RCU/NMI-RCU.txt | |||
@@ -34,7 +34,7 @@ NMI handler. | |||
34 | cpu = smp_processor_id(); | 34 | cpu = smp_processor_id(); |
35 | ++nmi_count(cpu); | 35 | ++nmi_count(cpu); |
36 | 36 | ||
37 | if (!rcu_dereference(nmi_callback)(regs, cpu)) | 37 | if (!rcu_dereference_sched(nmi_callback)(regs, cpu)) |
38 | default_do_nmi(regs); | 38 | default_do_nmi(regs); |
39 | 39 | ||
40 | nmi_exit(); | 40 | nmi_exit(); |
@@ -47,12 +47,13 @@ function pointer. If this handler returns zero, do_nmi() invokes the | |||
47 | default_do_nmi() function to handle a machine-specific NMI. Finally, | 47 | default_do_nmi() function to handle a machine-specific NMI. Finally, |
48 | preemption is restored. | 48 | preemption is restored. |
49 | 49 | ||
50 | Strictly speaking, rcu_dereference() is not needed, since this code runs | 50 | In theory, rcu_dereference_sched() is not needed, since this code runs |
51 | only on i386, which does not need rcu_dereference() anyway. However, | 51 | only on i386, which in theory does not need rcu_dereference_sched() |
52 | it is a good documentation aid, particularly for anyone attempting to | 52 | anyway. However, in practice it is a good documentation aid, particularly |
53 | do something similar on Alpha. | 53 | for anyone attempting to do something similar on Alpha or on systems |
54 | with aggressive optimizing compilers. | ||
54 | 55 | ||
55 | Quick Quiz: Why might the rcu_dereference() be necessary on Alpha, | 56 | Quick Quiz: Why might the rcu_dereference_sched() be necessary on Alpha, |
56 | given that the code referenced by the pointer is read-only? | 57 | given that the code referenced by the pointer is read-only? |
57 | 58 | ||
58 | 59 | ||
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively. | |||
99 | 100 | ||
100 | Answer to Quick Quiz | 101 | Answer to Quick Quiz |
101 | 102 | ||
102 | Why might the rcu_dereference() be necessary on Alpha, given | 103 | Why might the rcu_dereference_sched() be necessary on Alpha, given |
103 | that the code referenced by the pointer is read-only? | 104 | that the code referenced by the pointer is read-only? |
104 | 105 | ||
105 | Answer: The caller to set_nmi_callback() might well have | 106 | Answer: The caller to set_nmi_callback() might well have |
106 | initialized some data that is to be used by the | 107 | initialized some data that is to be used by the new NMI |
107 | new NMI handler. In this case, the rcu_dereference() | 108 | handler. In this case, the rcu_dereference_sched() would |
108 | would be needed, because otherwise a CPU that received | 109 | be needed, because otherwise a CPU that received an NMI |
109 | an NMI just after the new handler was set might see | 110 | just after the new handler was set might see the pointer |
110 | the pointer to the new NMI handler, but the old | 111 | to the new NMI handler, but the old pre-initialized |
111 | pre-initialized version of the handler's data. | 112 | version of the handler's data. |
112 | 113 | ||
113 | More important, the rcu_dereference() makes it clear | 114 | This same sad story can happen on other CPUs when using |
114 | to someone reading the code that the pointer is being | 115 | a compiler with aggressive pointer-value speculation |
115 | protected by RCU. | 116 | optimizations. |
117 | |||
118 | More important, the rcu_dereference_sched() makes it | ||
119 | clear to someone reading the code that the pointer is | ||
120 | being protected by RCU-sched. | ||
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index cbc180f90194..790d1a812376 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt | |||
@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome! | |||
260 | The reason that it is permissible to use RCU list-traversal | 260 | The reason that it is permissible to use RCU list-traversal |
261 | primitives when the update-side lock is held is that doing so | 261 | primitives when the update-side lock is held is that doing so |
262 | can be quite helpful in reducing code bloat when common code is | 262 | can be quite helpful in reducing code bloat when common code is |
263 | shared between readers and updaters. | 263 | shared between readers and updaters. Additional primitives |
264 | are provided for this case, as discussed in lockdep.txt. | ||
264 | 265 | ||
265 | 10. Conversely, if you are in an RCU read-side critical section, | 266 | 10. Conversely, if you are in an RCU read-side critical section, |
266 | and you don't hold the appropriate update-side lock, you -must- | 267 | and you don't hold the appropriate update-side lock, you -must- |
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome! | |||
344 | requiring SRCU's read-side deadlock immunity or low read-side | 345 | requiring SRCU's read-side deadlock immunity or low read-side |
345 | realtime latency. | 346 | realtime latency. |
346 | 347 | ||
347 | Note that, rcu_assign_pointer() and rcu_dereference() relate to | 348 | Note that, rcu_assign_pointer() relates to SRCU just as they do |
348 | SRCU just as they do to other forms of RCU. | 349 | to other forms of RCU. |
349 | 350 | ||
350 | 15. The whole point of call_rcu(), synchronize_rcu(), and friends | 351 | 15. The whole point of call_rcu(), synchronize_rcu(), and friends |
351 | is to wait until all pre-existing readers have finished before | 352 | is to wait until all pre-existing readers have finished before |
diff --git a/Documentation/RCU/lockdep.txt b/Documentation/RCU/lockdep.txt index fe24b58627bd..d7a49b2f6994 100644 --- a/Documentation/RCU/lockdep.txt +++ b/Documentation/RCU/lockdep.txt | |||
@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives: | |||
32 | srcu_dereference(p, sp): | 32 | srcu_dereference(p, sp): |
33 | Check for SRCU read-side critical section. | 33 | Check for SRCU read-side critical section. |
34 | rcu_dereference_check(p, c): | 34 | rcu_dereference_check(p, c): |
35 | Use explicit check expression "c". | 35 | Use explicit check expression "c". This is useful in |
36 | code that is invoked by both readers and updaters. | ||
36 | rcu_dereference_raw(p) | 37 | rcu_dereference_raw(p) |
37 | Don't check. (Use sparingly, if at all.) | 38 | Don't check. (Use sparingly, if at all.) |
39 | rcu_dereference_protected(p, c): | ||
40 | Use explicit check expression "c", and omit all barriers | ||
41 | and compiler constraints. This is useful when the data | ||
42 | structure cannot change, for example, in code that is | ||
43 | invoked only by updaters. | ||
44 | rcu_access_pointer(p): | ||
45 | Return the value of the pointer and omit all barriers, | ||
46 | but retain the compiler constraints that prevent duplicating | ||
47 | or coalescsing. This is useful when when testing the | ||
48 | value of the pointer itself, for example, against NULL. | ||
38 | 49 | ||
39 | The rcu_dereference_check() check expression can be any boolean | 50 | The rcu_dereference_check() check expression can be any boolean |
40 | expression, but would normally include one of the rcu_read_lock_held() | 51 | expression, but would normally include one of the rcu_read_lock_held() |
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla | |||
59 | RCU read-side critical sections, in case (2) the ->file_lock prevents | 70 | RCU read-side critical sections, in case (2) the ->file_lock prevents |
60 | any change from taking place, and finally, in case (3) the current task | 71 | any change from taking place, and finally, in case (3) the current task |
61 | is the only task accessing the file_struct, again preventing any change | 72 | is the only task accessing the file_struct, again preventing any change |
62 | from taking place. | 73 | from taking place. If the above statement was invoked only from updater |
74 | code, it could instead be written as follows: | ||
75 | |||
76 | file = rcu_dereference_protected(fdt->fd[fd], | ||
77 | lockdep_is_held(&files->file_lock) || | ||
78 | atomic_read(&files->count) == 1); | ||
79 | |||
80 | This would verify cases #2 and #3 above, and furthermore lockdep would | ||
81 | complain if this was used in an RCU read-side critical section unless one | ||
82 | of these two cases held. Because rcu_dereference_protected() omits all | ||
83 | barriers and compiler constraints, it generates better code than do the | ||
84 | other flavors of rcu_dereference(). On the other hand, it is illegal | ||
85 | to use rcu_dereference_protected() if either the RCU-protected pointer | ||
86 | or the RCU-protected data that it points to can change concurrently. | ||
63 | 87 | ||
64 | There are currently only "universal" versions of the rcu_assign_pointer() | 88 | There are currently only "universal" versions of the rcu_assign_pointer() |
65 | and RCU list-/tree-traversal primitives, which do not (yet) check for | 89 | and RCU list-/tree-traversal primitives, which do not (yet) check for |
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 1dc00ee97163..cfaac34c4557 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt | |||
@@ -840,6 +840,12 @@ SRCU: Initialization/cleanup | |||
840 | init_srcu_struct | 840 | init_srcu_struct |
841 | cleanup_srcu_struct | 841 | cleanup_srcu_struct |
842 | 842 | ||
843 | All: lockdep-checked RCU-protected pointer access | ||
844 | |||
845 | rcu_dereference_check | ||
846 | rcu_dereference_protected | ||
847 | rcu_access_pointer | ||
848 | |||
843 | See the comment headers in the source code (or the docbook generated | 849 | See the comment headers in the source code (or the docbook generated |
844 | from them) for more information. | 850 | from them) for more information. |
845 | 851 | ||
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index 6fab97ea7e6b..508b5b2b0289 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt | |||
@@ -1162,8 +1162,8 @@ where a driver received a request ala this before: | |||
1162 | 1162 | ||
1163 | As mentioned, there is no virtual mapping of a bio. For DMA, this is | 1163 | As mentioned, there is no virtual mapping of a bio. For DMA, this is |
1164 | not a problem as the driver probably never will need a virtual mapping. | 1164 | not a problem as the driver probably never will need a virtual mapping. |
1165 | Instead it needs a bus mapping (pci_map_page for a single segment or | 1165 | Instead it needs a bus mapping (dma_map_page for a single segment or |
1166 | use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For | 1166 | use dma_map_sg for scatter gather) to be able to ship it to the driver. For |
1167 | PIO drivers (or drivers that need to revert to PIO transfer once in a | 1167 | PIO drivers (or drivers that need to revert to PIO transfer once in a |
1168 | while (IDE for example)), where the CPU is doing the actual data | 1168 | while (IDE for example)), where the CPU is doing the actual data |
1169 | transfer a virtual mapping is needed. If the driver supports highmem I/O, | 1169 | transfer a virtual mapping is needed. If the driver supports highmem I/O, |
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index 8490480ce432..c0fc1c75fd88 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt | |||
@@ -68,6 +68,22 @@ like: | |||
68 | SYN_MT_REPORT | 68 | SYN_MT_REPORT |
69 | SYN_REPORT | 69 | SYN_REPORT |
70 | 70 | ||
71 | Here is the sequence after lifting one of the fingers: | ||
72 | |||
73 | ABS_MT_POSITION_X | ||
74 | ABS_MT_POSITION_Y | ||
75 | SYN_MT_REPORT | ||
76 | SYN_REPORT | ||
77 | |||
78 | And here is the sequence after lifting the remaining finger: | ||
79 | |||
80 | SYN_MT_REPORT | ||
81 | SYN_REPORT | ||
82 | |||
83 | If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the | ||
84 | ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the | ||
85 | last SYN_REPORT will be dropped by the input core, resulting in no | ||
86 | zero-finger event reaching userland. | ||
71 | 87 | ||
72 | Event Semantics | 88 | Event Semantics |
73 | --------------- | 89 | --------------- |
@@ -217,11 +233,6 @@ where examples can be found. | |||
217 | difference between the contact position and the approaching tool position | 233 | difference between the contact position and the approaching tool position |
218 | could be used to derive tilt. | 234 | could be used to derive tilt. |
219 | [2] The list can of course be extended. | 235 | [2] The list can of course be extended. |
220 | [3] The multi-touch X driver is currently in the prototyping stage. At the | 236 | [3] Multitouch X driver project: http://bitmath.org/code/multitouch/. |
221 | time of writing (April 2009), the MT protocol is not yet merged, and the | ||
222 | prototype implements finger matching, basic mouse support and two-finger | ||
223 | scrolling. The project aims at improving the quality of current multi-touch | ||
224 | functionality available in the Synaptics X driver, and in addition | ||
225 | implement more advanced gestures. | ||
226 | [4] See the section on event computation. | 237 | [4] See the section on event computation. |
227 | [5] See the section on finger tracking. | 238 | [5] See the section on finger tracking. |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e4cbca58536c..e2202e93b148 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -320,11 +320,6 @@ and is between 256 and 4096 characters. It is defined in the file | |||
320 | amd_iommu= [HW,X86-84] | 320 | amd_iommu= [HW,X86-84] |
321 | Pass parameters to the AMD IOMMU driver in the system. | 321 | Pass parameters to the AMD IOMMU driver in the system. |
322 | Possible values are: | 322 | Possible values are: |
323 | isolate - enable device isolation (each device, as far | ||
324 | as possible, will get its own protection | ||
325 | domain) [default] | ||
326 | share - put every device behind one IOMMU into the | ||
327 | same protection domain | ||
328 | fullflush - enable flushing of IO/TLB entries when | 323 | fullflush - enable flushing of IO/TLB entries when |
329 | they are unmapped. Otherwise they are | 324 | they are unmapped. Otherwise they are |
330 | flushed before they will be reused, which | 325 | flushed before they will be reused, which |
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index c6416a398163..baa8fde8bd16 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt | |||
@@ -656,6 +656,7 @@ struct kvm_clock_data { | |||
656 | 4.29 KVM_GET_VCPU_EVENTS | 656 | 4.29 KVM_GET_VCPU_EVENTS |
657 | 657 | ||
658 | Capability: KVM_CAP_VCPU_EVENTS | 658 | Capability: KVM_CAP_VCPU_EVENTS |
659 | Extended by: KVM_CAP_INTR_SHADOW | ||
659 | Architectures: x86 | 660 | Architectures: x86 |
660 | Type: vm ioctl | 661 | Type: vm ioctl |
661 | Parameters: struct kvm_vcpu_event (out) | 662 | Parameters: struct kvm_vcpu_event (out) |
@@ -676,7 +677,7 @@ struct kvm_vcpu_events { | |||
676 | __u8 injected; | 677 | __u8 injected; |
677 | __u8 nr; | 678 | __u8 nr; |
678 | __u8 soft; | 679 | __u8 soft; |
679 | __u8 pad; | 680 | __u8 shadow; |
680 | } interrupt; | 681 | } interrupt; |
681 | struct { | 682 | struct { |
682 | __u8 injected; | 683 | __u8 injected; |
@@ -688,9 +689,13 @@ struct kvm_vcpu_events { | |||
688 | __u32 flags; | 689 | __u32 flags; |
689 | }; | 690 | }; |
690 | 691 | ||
692 | KVM_VCPUEVENT_VALID_SHADOW may be set in the flags field to signal that | ||
693 | interrupt.shadow contains a valid state. Otherwise, this field is undefined. | ||
694 | |||
691 | 4.30 KVM_SET_VCPU_EVENTS | 695 | 4.30 KVM_SET_VCPU_EVENTS |
692 | 696 | ||
693 | Capability: KVM_CAP_VCPU_EVENTS | 697 | Capability: KVM_CAP_VCPU_EVENTS |
698 | Extended by: KVM_CAP_INTR_SHADOW | ||
694 | Architectures: x86 | 699 | Architectures: x86 |
695 | Type: vm ioctl | 700 | Type: vm ioctl |
696 | Parameters: struct kvm_vcpu_event (in) | 701 | Parameters: struct kvm_vcpu_event (in) |
@@ -709,6 +714,139 @@ current in-kernel state. The bits are: | |||
709 | KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel | 714 | KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel |
710 | KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector | 715 | KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector |
711 | 716 | ||
717 | If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in | ||
718 | the flags field to signal that interrupt.shadow contains a valid state and | ||
719 | shall be written into the VCPU. | ||
720 | |||
721 | 4.32 KVM_GET_DEBUGREGS | ||
722 | |||
723 | Capability: KVM_CAP_DEBUGREGS | ||
724 | Architectures: x86 | ||
725 | Type: vm ioctl | ||
726 | Parameters: struct kvm_debugregs (out) | ||
727 | Returns: 0 on success, -1 on error | ||
728 | |||
729 | Reads debug registers from the vcpu. | ||
730 | |||
731 | struct kvm_debugregs { | ||
732 | __u64 db[4]; | ||
733 | __u64 dr6; | ||
734 | __u64 dr7; | ||
735 | __u64 flags; | ||
736 | __u64 reserved[9]; | ||
737 | }; | ||
738 | |||
739 | 4.33 KVM_SET_DEBUGREGS | ||
740 | |||
741 | Capability: KVM_CAP_DEBUGREGS | ||
742 | Architectures: x86 | ||
743 | Type: vm ioctl | ||
744 | Parameters: struct kvm_debugregs (in) | ||
745 | Returns: 0 on success, -1 on error | ||
746 | |||
747 | Writes debug registers into the vcpu. | ||
748 | |||
749 | See KVM_GET_DEBUGREGS for the data structure. The flags field is unused | ||
750 | yet and must be cleared on entry. | ||
751 | |||
752 | 4.34 KVM_SET_USER_MEMORY_REGION | ||
753 | |||
754 | Capability: KVM_CAP_USER_MEM | ||
755 | Architectures: all | ||
756 | Type: vm ioctl | ||
757 | Parameters: struct kvm_userspace_memory_region (in) | ||
758 | Returns: 0 on success, -1 on error | ||
759 | |||
760 | struct kvm_userspace_memory_region { | ||
761 | __u32 slot; | ||
762 | __u32 flags; | ||
763 | __u64 guest_phys_addr; | ||
764 | __u64 memory_size; /* bytes */ | ||
765 | __u64 userspace_addr; /* start of the userspace allocated memory */ | ||
766 | }; | ||
767 | |||
768 | /* for kvm_memory_region::flags */ | ||
769 | #define KVM_MEM_LOG_DIRTY_PAGES 1UL | ||
770 | |||
771 | This ioctl allows the user to create or modify a guest physical memory | ||
772 | slot. When changing an existing slot, it may be moved in the guest | ||
773 | physical memory space, or its flags may be modified. It may not be | ||
774 | resized. Slots may not overlap in guest physical address space. | ||
775 | |||
776 | Memory for the region is taken starting at the address denoted by the | ||
777 | field userspace_addr, which must point at user addressable memory for | ||
778 | the entire memory slot size. Any object may back this memory, including | ||
779 | anonymous memory, ordinary files, and hugetlbfs. | ||
780 | |||
781 | It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr | ||
782 | be identical. This allows large pages in the guest to be backed by large | ||
783 | pages in the host. | ||
784 | |||
785 | The flags field supports just one flag, KVM_MEM_LOG_DIRTY_PAGES, which | ||
786 | instructs kvm to keep track of writes to memory within the slot. See | ||
787 | the KVM_GET_DIRTY_LOG ioctl. | ||
788 | |||
789 | When the KVM_CAP_SYNC_MMU capability, changes in the backing of the memory | ||
790 | region are automatically reflected into the guest. For example, an mmap() | ||
791 | that affects the region will be made visible immediately. Another example | ||
792 | is madvise(MADV_DROP). | ||
793 | |||
794 | It is recommended to use this API instead of the KVM_SET_MEMORY_REGION ioctl. | ||
795 | The KVM_SET_MEMORY_REGION does not allow fine grained control over memory | ||
796 | allocation and is deprecated. | ||
797 | |||
798 | 4.35 KVM_SET_TSS_ADDR | ||
799 | |||
800 | Capability: KVM_CAP_SET_TSS_ADDR | ||
801 | Architectures: x86 | ||
802 | Type: vm ioctl | ||
803 | Parameters: unsigned long tss_address (in) | ||
804 | Returns: 0 on success, -1 on error | ||
805 | |||
806 | This ioctl defines the physical address of a three-page region in the guest | ||
807 | physical address space. The region must be within the first 4GB of the | ||
808 | guest physical address space and must not conflict with any memory slot | ||
809 | or any mmio address. The guest may malfunction if it accesses this memory | ||
810 | region. | ||
811 | |||
812 | This ioctl is required on Intel-based hosts. This is needed on Intel hardware | ||
813 | because of a quirk in the virtualization implementation (see the internals | ||
814 | documentation when it pops into existence). | ||
815 | |||
816 | 4.36 KVM_ENABLE_CAP | ||
817 | |||
818 | Capability: KVM_CAP_ENABLE_CAP | ||
819 | Architectures: ppc | ||
820 | Type: vcpu ioctl | ||
821 | Parameters: struct kvm_enable_cap (in) | ||
822 | Returns: 0 on success; -1 on error | ||
823 | |||
824 | +Not all extensions are enabled by default. Using this ioctl the application | ||
825 | can enable an extension, making it available to the guest. | ||
826 | |||
827 | On systems that do not support this ioctl, it always fails. On systems that | ||
828 | do support it, it only works for extensions that are supported for enablement. | ||
829 | |||
830 | To check if a capability can be enabled, the KVM_CHECK_EXTENSION ioctl should | ||
831 | be used. | ||
832 | |||
833 | struct kvm_enable_cap { | ||
834 | /* in */ | ||
835 | __u32 cap; | ||
836 | |||
837 | The capability that is supposed to get enabled. | ||
838 | |||
839 | __u32 flags; | ||
840 | |||
841 | A bitfield indicating future enhancements. Has to be 0 for now. | ||
842 | |||
843 | __u64 args[4]; | ||
844 | |||
845 | Arguments for enabling a feature. If a feature needs initial values to | ||
846 | function properly, this is the place to put them. | ||
847 | |||
848 | __u8 pad[64]; | ||
849 | }; | ||
712 | 850 | ||
713 | 5. The kvm_run structure | 851 | 5. The kvm_run structure |
714 | 852 | ||
@@ -820,6 +958,13 @@ executed a memory-mapped I/O instruction which could not be satisfied | |||
820 | by kvm. The 'data' member contains the written data if 'is_write' is | 958 | by kvm. The 'data' member contains the written data if 'is_write' is |
821 | true, and should be filled by application code otherwise. | 959 | true, and should be filled by application code otherwise. |
822 | 960 | ||
961 | NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO and KVM_EXIT_OSI, the corresponding | ||
962 | operations are complete (and guest state is consistent) only after userspace | ||
963 | has re-entered the kernel with KVM_RUN. The kernel side will first finish | ||
964 | incomplete operations and then check for pending signals. Userspace | ||
965 | can re-enter the guest with an unmasked signal pending to complete | ||
966 | pending operations. | ||
967 | |||
823 | /* KVM_EXIT_HYPERCALL */ | 968 | /* KVM_EXIT_HYPERCALL */ |
824 | struct { | 969 | struct { |
825 | __u64 nr; | 970 | __u64 nr; |
@@ -829,7 +974,9 @@ true, and should be filled by application code otherwise. | |||
829 | __u32 pad; | 974 | __u32 pad; |
830 | } hypercall; | 975 | } hypercall; |
831 | 976 | ||
832 | Unused. | 977 | Unused. This was once used for 'hypercall to userspace'. To implement |
978 | such functionality, use KVM_EXIT_IO (x86) or KVM_EXIT_MMIO (all except s390). | ||
979 | Note KVM_EXIT_IO is significantly faster than KVM_EXIT_MMIO. | ||
833 | 980 | ||
834 | /* KVM_EXIT_TPR_ACCESS */ | 981 | /* KVM_EXIT_TPR_ACCESS */ |
835 | struct { | 982 | struct { |
@@ -870,6 +1017,19 @@ s390 specific. | |||
870 | 1017 | ||
871 | powerpc specific. | 1018 | powerpc specific. |
872 | 1019 | ||
1020 | /* KVM_EXIT_OSI */ | ||
1021 | struct { | ||
1022 | __u64 gprs[32]; | ||
1023 | } osi; | ||
1024 | |||
1025 | MOL uses a special hypercall interface it calls 'OSI'. To enable it, we catch | ||
1026 | hypercalls and exit with this exit struct that contains all the guest gprs. | ||
1027 | |||
1028 | If exit_reason is KVM_EXIT_OSI, then the vcpu has triggered such a hypercall. | ||
1029 | Userspace can now handle the hypercall and when it's done modify the gprs as | ||
1030 | necessary. Upon guest entry all guest GPRs will then be replaced by the values | ||
1031 | in this struct. | ||
1032 | |||
873 | /* Fix the size of the union. */ | 1033 | /* Fix the size of the union. */ |
874 | char padding[256]; | 1034 | char padding[256]; |
875 | }; | 1035 | }; |
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index 0e58b4539176..e8c8f4f06c67 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt | |||
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in | |||
41 | SOF_TIMESTAMPING_TX/RX determine how time stamps are generated. | 41 | SOF_TIMESTAMPING_TX/RX determine how time stamps are generated. |
42 | SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the | 42 | SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the |
43 | following control message: | 43 | following control message: |
44 | struct scm_timestamping { | 44 | |
45 | struct timespec systime; | 45 | struct scm_timestamping { |
46 | struct timespec hwtimetrans; | 46 | struct timespec systime; |
47 | struct timespec hwtimeraw; | 47 | struct timespec hwtimetrans; |
48 | }; | 48 | struct timespec hwtimeraw; |
49 | }; | ||
49 | 50 | ||
50 | recvmsg() can be used to get this control message for regular incoming | 51 | recvmsg() can be used to get this control message for regular incoming |
51 | packets. For send time stamps the outgoing packet is looped back to | 52 | packets. For send time stamps the outgoing packet is looped back to |
@@ -87,12 +88,13 @@ by the network device and will be empty without that support. | |||
87 | SIOCSHWTSTAMP: | 88 | SIOCSHWTSTAMP: |
88 | 89 | ||
89 | Hardware time stamping must also be initialized for each device driver | 90 | Hardware time stamping must also be initialized for each device driver |
90 | that is expected to do hardware time stamping. The parameter is: | 91 | that is expected to do hardware time stamping. The parameter is defined in |
92 | /include/linux/net_tstamp.h as: | ||
91 | 93 | ||
92 | struct hwtstamp_config { | 94 | struct hwtstamp_config { |
93 | int flags; /* no flags defined right now, must be zero */ | 95 | int flags; /* no flags defined right now, must be zero */ |
94 | int tx_type; /* HWTSTAMP_TX_* */ | 96 | int tx_type; /* HWTSTAMP_TX_* */ |
95 | int rx_filter; /* HWTSTAMP_FILTER_* */ | 97 | int rx_filter; /* HWTSTAMP_FILTER_* */ |
96 | }; | 98 | }; |
97 | 99 | ||
98 | Desired behavior is passed into the kernel and to a specific device by | 100 | Desired behavior is passed into the kernel and to a specific device by |
@@ -139,42 +141,56 @@ enum { | |||
139 | /* time stamp any incoming packet */ | 141 | /* time stamp any incoming packet */ |
140 | HWTSTAMP_FILTER_ALL, | 142 | HWTSTAMP_FILTER_ALL, |
141 | 143 | ||
142 | /* return value: time stamp all packets requested plus some others */ | 144 | /* return value: time stamp all packets requested plus some others */ |
143 | HWTSTAMP_FILTER_SOME, | 145 | HWTSTAMP_FILTER_SOME, |
144 | 146 | ||
145 | /* PTP v1, UDP, any kind of event packet */ | 147 | /* PTP v1, UDP, any kind of event packet */ |
146 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, | 148 | HWTSTAMP_FILTER_PTP_V1_L4_EVENT, |
147 | 149 | ||
148 | ... | 150 | /* for the complete list of values, please check |
151 | * the include file /include/linux/net_tstamp.h | ||
152 | */ | ||
149 | }; | 153 | }; |
150 | 154 | ||
151 | 155 | ||
152 | DEVICE IMPLEMENTATION | 156 | DEVICE IMPLEMENTATION |
153 | 157 | ||
154 | A driver which supports hardware time stamping must support the | 158 | A driver which supports hardware time stamping must support the |
155 | SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored | 159 | SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with |
156 | in the skb with skb_hwtstamp_set(). | 160 | the actual values as described in the section on SIOCSHWTSTAMP. |
161 | |||
162 | Time stamps for received packets must be stored in the skb. To get a pointer | ||
163 | to the shared time stamp structure of the skb call skb_hwtstamps(). Then | ||
164 | set the time stamps in the structure: | ||
165 | |||
166 | struct skb_shared_hwtstamps { | ||
167 | /* hardware time stamp transformed into duration | ||
168 | * since arbitrary point in time | ||
169 | */ | ||
170 | ktime_t hwtstamp; | ||
171 | ktime_t syststamp; /* hwtstamp transformed to system time base */ | ||
172 | }; | ||
157 | 173 | ||
158 | Time stamps for outgoing packets are to be generated as follows: | 174 | Time stamps for outgoing packets are to be generated as follows: |
159 | - In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware() | 175 | - In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero. |
160 | returns non-zero. If yes, then the driver is expected | 176 | If yes, then the driver is expected to do hardware time stamping. |
161 | to do hardware time stamping. | ||
162 | - If this is possible for the skb and requested, then declare | 177 | - If this is possible for the skb and requested, then declare |
163 | that the driver is doing the time stamping by calling | 178 | that the driver is doing the time stamping by setting the field |
164 | skb_hwtstamp_tx_in_progress(). A driver not supporting | 179 | skb_tx(skb)->in_progress non-zero. You might want to keep a pointer |
165 | hardware time stamping doesn't do that. A driver must never | 180 | to the associated skb for the next step and not free the skb. A driver |
166 | touch sk_buff::tstamp! It is used to store how time stamping | 181 | not supporting hardware time stamping doesn't do that. A driver must |
167 | for an outgoing packets is to be done. | 182 | never touch sk_buff::tstamp! It is used to store software generated |
183 | time stamps by the network subsystem. | ||
168 | - As soon as the driver has sent the packet and/or obtained a | 184 | - As soon as the driver has sent the packet and/or obtained a |
169 | hardware time stamp for it, it passes the time stamp back by | 185 | hardware time stamp for it, it passes the time stamp back by |
170 | calling skb_hwtstamp_tx() with the original skb, the raw | 186 | calling skb_hwtstamp_tx() with the original skb, the raw |
171 | hardware time stamp and a handle to the device (necessary | 187 | hardware time stamp. skb_hwtstamp_tx() clones the original skb and |
172 | to convert the hardware time stamp to system time). If obtaining | 188 | adds the timestamps, therefore the original skb has to be freed now. |
173 | the hardware time stamp somehow fails, then the driver should | 189 | If obtaining the hardware time stamp somehow fails, then the driver |
174 | not fall back to software time stamping. The rationale is that | 190 | should not fall back to software time stamping. The rationale is that |
175 | this would occur at a later time in the processing pipeline | 191 | this would occur at a later time in the processing pipeline than other |
176 | than other software time stamping and therefore could lead | 192 | software time stamping and therefore could lead to unexpected deltas |
177 | to unexpected deltas between time stamps. | 193 | between time stamps. |
178 | - If the driver did not call skb_hwtstamp_tx_in_progress(), then | 194 | - If the driver did not call set skb_tx(skb)->in_progress, then |
179 | dev_hard_start_xmit() checks whether software time stamping | 195 | dev_hard_start_xmit() checks whether software time stamping |
180 | is wanted as fallback and potentially generates the time stamp. | 196 | is wanted as fallback and potentially generates the time stamp. |
diff --git a/MAINTAINERS b/MAINTAINERS index c3e9c3633b75..0716c65c05c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -485,8 +485,8 @@ S: Maintained | |||
485 | F: drivers/input/mouse/bcm5974.c | 485 | F: drivers/input/mouse/bcm5974.c |
486 | 486 | ||
487 | APPLE SMC DRIVER | 487 | APPLE SMC DRIVER |
488 | M: Nicolas Boichat <nicolas@boichat.ch> | 488 | M: Henrik Rydberg <rydberg@euromail.se> |
489 | L: mactel-linux-devel@lists.sourceforge.net | 489 | L: lm-sensors@lm-sensors.org |
490 | S: Maintained | 490 | S: Maintained |
491 | F: drivers/hwmon/applesmc.c | 491 | F: drivers/hwmon/applesmc.c |
492 | 492 | ||
@@ -971,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
971 | W: http://www.mcuos.com | 971 | W: http://www.mcuos.com |
972 | S: Maintained | 972 | S: Maintained |
973 | 973 | ||
974 | ARM/U300 MACHINE SUPPORT | ||
975 | M: Linus Walleij <linus.walleij@stericsson.com> | ||
976 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
977 | S: Supported | ||
978 | F: arch/arm/mach-u300/ | ||
979 | F: drivers/i2c/busses/i2c-stu300.c | ||
980 | F: drivers/rtc/rtc-coh901331.c | ||
981 | F: drivers/watchdog/coh901327_wdt.c | ||
982 | F: drivers/dma/coh901318* | ||
983 | |||
974 | ARM/U8500 ARM ARCHITECTURE | 984 | ARM/U8500 ARM ARCHITECTURE |
975 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | 985 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> |
976 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 986 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 34 | 3 | SUBLEVEL = 34 |
4 | EXTRAVERSION = -rc3 | 4 | EXTRAVERSION = -rc5 |
5 | NAME = Man-Eating Seals of Antiquity | 5 | NAME = Sheep on Meth |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
8 | # To see a list of typical targets execute "make help" | 8 | # To see a list of typical targets execute "make help" |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 0f23009170a1..6ab6b337a913 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -172,7 +172,7 @@ not_angel: | |||
172 | adr r0, LC0 | 172 | adr r0, LC0 |
173 | ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) | 173 | ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) |
174 | THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) | 174 | THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) |
175 | THUMB( ldr sp, [r0, #28] ) | 175 | THUMB( ldr sp, [r0, #32] ) |
176 | subs r0, r0, r1 @ calculate the delta offset | 176 | subs r0, r0, r1 @ calculate the delta offset |
177 | 177 | ||
178 | @ if delta is zero, we are | 178 | @ if delta is zero, we are |
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 7f36d00600b4..feb988a7ec37 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h | |||
@@ -11,7 +11,11 @@ | |||
11 | 11 | ||
12 | #define kmap_prot PAGE_KERNEL | 12 | #define kmap_prot PAGE_KERNEL |
13 | 13 | ||
14 | #define flush_cache_kmaps() flush_cache_all() | 14 | #define flush_cache_kmaps() \ |
15 | do { \ | ||
16 | if (cache_is_vivt()) \ | ||
17 | flush_cache_all(); \ | ||
18 | } while (0) | ||
15 | 19 | ||
16 | extern pte_t *pkmap_page_table; | 20 | extern pte_t *pkmap_page_table; |
17 | 21 | ||
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page); | |||
21 | extern void *kmap_high_get(struct page *page); | 25 | extern void *kmap_high_get(struct page *page); |
22 | extern void kunmap_high(struct page *page); | 26 | extern void kunmap_high(struct page *page); |
23 | 27 | ||
28 | extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte); | ||
29 | extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); | ||
30 | |||
31 | /* | ||
32 | * The following functions are already defined by <linux/highmem.h> | ||
33 | * when CONFIG_HIGHMEM is not set. | ||
34 | */ | ||
35 | #ifdef CONFIG_HIGHMEM | ||
24 | extern void *kmap(struct page *page); | 36 | extern void *kmap(struct page *page); |
25 | extern void kunmap(struct page *page); | 37 | extern void kunmap(struct page *page); |
26 | extern void *kmap_atomic(struct page *page, enum km_type type); | 38 | extern void *kmap_atomic(struct page *page, enum km_type type); |
27 | extern void kunmap_atomic(void *kvaddr, enum km_type type); | 39 | extern void kunmap_atomic(void *kvaddr, enum km_type type); |
28 | extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 40 | extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); |
29 | extern struct page *kmap_atomic_to_page(const void *ptr); | 41 | extern struct page *kmap_atomic_to_page(const void *ptr); |
42 | #endif | ||
30 | 43 | ||
31 | #endif | 44 | #endif |
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c019949a5189..c4b2ea3fbe42 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h | |||
@@ -18,6 +18,7 @@ enum km_type { | |||
18 | KM_IRQ1, | 18 | KM_IRQ1, |
19 | KM_SOFTIRQ0, | 19 | KM_SOFTIRQ0, |
20 | KM_SOFTIRQ1, | 20 | KM_SOFTIRQ1, |
21 | KM_L1_CACHE, | ||
21 | KM_L2_CACHE, | 22 | KM_L2_CACHE, |
22 | KM_TYPE_NR | 23 | KM_TYPE_NR |
23 | }; | 24 | }; |
diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h index bf65e9f4525d..47f023aa8495 100644 --- a/arch/arm/include/asm/ucontext.h +++ b/arch/arm/include/asm/ucontext.h | |||
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe { | |||
59 | #endif /* CONFIG_IWMMXT */ | 59 | #endif /* CONFIG_IWMMXT */ |
60 | 60 | ||
61 | #ifdef CONFIG_VFP | 61 | #ifdef CONFIG_VFP |
62 | #if __LINUX_ARM_ARCH__ < 6 | ||
63 | /* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra | ||
64 | * word after the registers, and a word of padding at the end for | ||
65 | * alignment. */ | ||
66 | #define VFP_MAGIC 0x56465001 | 62 | #define VFP_MAGIC 0x56465001 |
67 | #define VFP_STORAGE_SIZE 152 | ||
68 | #else | ||
69 | #define VFP_MAGIC 0x56465002 | ||
70 | #define VFP_STORAGE_SIZE 144 | ||
71 | #endif | ||
72 | 63 | ||
73 | struct vfp_sigframe | 64 | struct vfp_sigframe |
74 | { | 65 | { |
75 | unsigned long magic; | 66 | unsigned long magic; |
76 | unsigned long size; | 67 | unsigned long size; |
77 | union vfp_state storage; | 68 | struct user_vfp ufp; |
78 | }; | 69 | struct user_vfp_exc ufp_exc; |
70 | } __attribute__((__aligned__(8))); | ||
71 | |||
72 | /* | ||
73 | * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc, | ||
74 | * 4 bytes padding. | ||
75 | */ | ||
76 | #define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe) | ||
77 | |||
79 | #endif /* CONFIG_VFP */ | 78 | #endif /* CONFIG_VFP */ |
80 | 79 | ||
81 | /* | 80 | /* |
@@ -91,7 +90,7 @@ struct aux_sigframe { | |||
91 | #ifdef CONFIG_IWMMXT | 90 | #ifdef CONFIG_IWMMXT |
92 | struct iwmmxt_sigframe iwmmxt; | 91 | struct iwmmxt_sigframe iwmmxt; |
93 | #endif | 92 | #endif |
94 | #if 0 && defined CONFIG_VFP /* Not yet saved. */ | 93 | #ifdef CONFIG_VFP |
95 | struct vfp_sigframe vfp; | 94 | struct vfp_sigframe vfp; |
96 | #endif | 95 | #endif |
97 | /* Something that isn't a valid magic number for any coprocessor. */ | 96 | /* Something that isn't a valid magic number for any coprocessor. */ |
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h index df95e050f9dd..05ac4b06876a 100644 --- a/arch/arm/include/asm/user.h +++ b/arch/arm/include/asm/user.h | |||
@@ -83,11 +83,21 @@ struct user{ | |||
83 | 83 | ||
84 | /* | 84 | /* |
85 | * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 | 85 | * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 |
86 | * are ignored by the ptrace system call. | 86 | * are ignored by the ptrace system call and the signal handler. |
87 | */ | 87 | */ |
88 | struct user_vfp { | 88 | struct user_vfp { |
89 | unsigned long long fpregs[32]; | 89 | unsigned long long fpregs[32]; |
90 | unsigned long fpscr; | 90 | unsigned long fpscr; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | /* | ||
94 | * VFP exception registers exposed to user space during signal delivery. | ||
95 | * Fields not relavant to the current VFP architecture are ignored. | ||
96 | */ | ||
97 | struct user_vfp_exc { | ||
98 | unsigned long fpexc; | ||
99 | unsigned long fpinst; | ||
100 | unsigned long fpinst2; | ||
101 | }; | ||
102 | |||
93 | #endif /* _ARM_USER_H */ | 103 | #endif /* _ARM_USER_H */ |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index e7714f367eb8..907d5a620bca 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
19 | #include <asm/ucontext.h> | 19 | #include <asm/ucontext.h> |
20 | #include <asm/unistd.h> | 20 | #include <asm/unistd.h> |
21 | #include <asm/vfp.h> | ||
21 | 22 | ||
22 | #include "ptrace.h" | 23 | #include "ptrace.h" |
23 | #include "signal.h" | 24 | #include "signal.h" |
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) | |||
175 | 176 | ||
176 | #endif | 177 | #endif |
177 | 178 | ||
179 | #ifdef CONFIG_VFP | ||
180 | |||
181 | static int preserve_vfp_context(struct vfp_sigframe __user *frame) | ||
182 | { | ||
183 | struct thread_info *thread = current_thread_info(); | ||
184 | struct vfp_hard_struct *h = &thread->vfpstate.hard; | ||
185 | const unsigned long magic = VFP_MAGIC; | ||
186 | const unsigned long size = VFP_STORAGE_SIZE; | ||
187 | int err = 0; | ||
188 | |||
189 | vfp_sync_hwstate(thread); | ||
190 | __put_user_error(magic, &frame->magic, err); | ||
191 | __put_user_error(size, &frame->size, err); | ||
192 | |||
193 | /* | ||
194 | * Copy the floating point registers. There can be unused | ||
195 | * registers see asm/hwcap.h for details. | ||
196 | */ | ||
197 | err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, | ||
198 | sizeof(h->fpregs)); | ||
199 | /* | ||
200 | * Copy the status and control register. | ||
201 | */ | ||
202 | __put_user_error(h->fpscr, &frame->ufp.fpscr, err); | ||
203 | |||
204 | /* | ||
205 | * Copy the exception registers. | ||
206 | */ | ||
207 | __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); | ||
208 | __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); | ||
209 | __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); | ||
210 | |||
211 | return err ? -EFAULT : 0; | ||
212 | } | ||
213 | |||
214 | static int restore_vfp_context(struct vfp_sigframe __user *frame) | ||
215 | { | ||
216 | struct thread_info *thread = current_thread_info(); | ||
217 | struct vfp_hard_struct *h = &thread->vfpstate.hard; | ||
218 | unsigned long magic; | ||
219 | unsigned long size; | ||
220 | unsigned long fpexc; | ||
221 | int err = 0; | ||
222 | |||
223 | __get_user_error(magic, &frame->magic, err); | ||
224 | __get_user_error(size, &frame->size, err); | ||
225 | |||
226 | if (err) | ||
227 | return -EFAULT; | ||
228 | if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) | ||
229 | return -EINVAL; | ||
230 | |||
231 | /* | ||
232 | * Copy the floating point registers. There can be unused | ||
233 | * registers see asm/hwcap.h for details. | ||
234 | */ | ||
235 | err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, | ||
236 | sizeof(h->fpregs)); | ||
237 | /* | ||
238 | * Copy the status and control register. | ||
239 | */ | ||
240 | __get_user_error(h->fpscr, &frame->ufp.fpscr, err); | ||
241 | |||
242 | /* | ||
243 | * Sanitise and restore the exception registers. | ||
244 | */ | ||
245 | __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); | ||
246 | /* Ensure the VFP is enabled. */ | ||
247 | fpexc |= FPEXC_EN; | ||
248 | /* Ensure FPINST2 is invalid and the exception flag is cleared. */ | ||
249 | fpexc &= ~(FPEXC_EX | FPEXC_FP2V); | ||
250 | h->fpexc = fpexc; | ||
251 | |||
252 | __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); | ||
253 | __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); | ||
254 | |||
255 | if (!err) | ||
256 | vfp_flush_hwstate(thread); | ||
257 | |||
258 | return err ? -EFAULT : 0; | ||
259 | } | ||
260 | |||
261 | #endif | ||
262 | |||
178 | /* | 263 | /* |
179 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. | 264 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. |
180 | */ | 265 | */ |
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) | |||
233 | err |= restore_iwmmxt_context(&aux->iwmmxt); | 318 | err |= restore_iwmmxt_context(&aux->iwmmxt); |
234 | #endif | 319 | #endif |
235 | #ifdef CONFIG_VFP | 320 | #ifdef CONFIG_VFP |
236 | // if (err == 0) | 321 | if (err == 0) |
237 | // err |= vfp_restore_state(&sf->aux.vfp); | 322 | err |= restore_vfp_context(&aux->vfp); |
238 | #endif | 323 | #endif |
239 | 324 | ||
240 | return err; | 325 | return err; |
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) | |||
348 | err |= preserve_iwmmxt_context(&aux->iwmmxt); | 433 | err |= preserve_iwmmxt_context(&aux->iwmmxt); |
349 | #endif | 434 | #endif |
350 | #ifdef CONFIG_VFP | 435 | #ifdef CONFIG_VFP |
351 | // if (err == 0) | 436 | if (err == 0) |
352 | // err |= vfp_save_state(&sf->aux.vfp); | 437 | err |= preserve_vfp_context(&aux->vfp); |
353 | #endif | 438 | #endif |
354 | __put_user_error(0, &aux->end_magic, err); | 439 | __put_user_error(0, &aux->end_magic, err); |
355 | 440 | ||
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 027dd570dcc3..d4004557532a 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_d | |||
16 | obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o | 16 | obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o |
17 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o | 17 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o |
18 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o | 18 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o |
19 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o | 19 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o |
20 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o | 20 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o |
21 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o | 21 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o |
22 | obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o | 22 | obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o |
23 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 23 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 987fab3d846a..9c5b48e68a71 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S | |||
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock) | |||
175 | orr r3, r3, #(1 << 29) /* bit 29 always set */ | 175 | orr r3, r3, #(1 << 29) /* bit 29 always set */ |
176 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] | 176 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] |
177 | 177 | ||
178 | wait_pllalock | ||
179 | |||
180 | /* Save PLLB setting and disable it */ | 178 | /* Save PLLB setting and disable it */ |
181 | ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 179 | ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] |
182 | str r3, .saved_pllbr | 180 | str r3, .saved_pllbr |
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock) | |||
184 | mov r3, #AT91_PMC_PLLCOUNT | 182 | mov r3, #AT91_PMC_PLLCOUNT |
185 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 183 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] |
186 | 184 | ||
187 | wait_pllblock | ||
188 | |||
189 | /* Turn off the main oscillator */ | 185 | /* Turn off the main oscillator */ |
190 | ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] | 186 | ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)] |
191 | bic r3, r3, #AT91_PMC_MOSCEN | 187 | bic r3, r3, #AT91_PMC_MOSCEN |
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock) | |||
205 | ldr r3, .saved_pllbr | 201 | ldr r3, .saved_pllbr |
206 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] | 202 | str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)] |
207 | 203 | ||
204 | tst r3, #(AT91_PMC_MUL & 0xff0000) | ||
205 | bne 1f | ||
206 | tst r3, #(AT91_PMC_MUL & ~0xff0000) | ||
207 | beq 2f | ||
208 | 1: | ||
208 | wait_pllblock | 209 | wait_pllblock |
210 | 2: | ||
209 | 211 | ||
210 | /* Restore PLLA setting */ | 212 | /* Restore PLLA setting */ |
211 | ldr r3, .saved_pllar | 213 | ldr r3, .saved_pllar |
212 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] | 214 | str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)] |
213 | 215 | ||
216 | tst r3, #(AT91_PMC_MUL & 0xff0000) | ||
217 | bne 3f | ||
218 | tst r3, #(AT91_PMC_MUL & ~0xff0000) | ||
219 | beq 4f | ||
220 | 3: | ||
214 | wait_pllalock | 221 | wait_pllalock |
222 | 4: | ||
215 | 223 | ||
216 | #ifdef SLOWDOWN_MASTER_CLOCK | 224 | #ifdef SLOWDOWN_MASTER_CLOCK |
217 | /* | 225 | /* |
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 2ccf670ce1ac..29c0a911df26 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c | |||
@@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring); | |||
2221 | int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | 2221 | int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ |
2222 | int dirtied /* non-zero if any of the pages were modified */ | 2222 | int dirtied /* non-zero if any of the pages were modified */ |
2223 | ) { | 2223 | ) { |
2224 | |||
2225 | int rc = 0; | ||
2224 | int regionIdx; | 2226 | int regionIdx; |
2225 | int segmentIdx; | 2227 | int segmentIdx; |
2226 | DMA_Region_t *region; | 2228 | DMA_Region_t *region; |
2227 | DMA_Segment_t *segment; | 2229 | DMA_Segment_t *segment; |
2228 | 2230 | ||
2231 | down(&memMap->lock); | ||
2232 | |||
2229 | for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { | 2233 | for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { |
2230 | region = &memMap->region[regionIdx]; | 2234 | region = &memMap->region[regionIdx]; |
2231 | 2235 | ||
@@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | |||
2239 | printk(KERN_ERR | 2243 | printk(KERN_ERR |
2240 | "%s: vmalloc'd pages are not yet supported\n", | 2244 | "%s: vmalloc'd pages are not yet supported\n", |
2241 | __func__); | 2245 | __func__); |
2242 | return -EINVAL; | 2246 | rc = -EINVAL; |
2247 | goto out; | ||
2243 | } | 2248 | } |
2244 | 2249 | ||
2245 | case DMA_MEM_TYPE_KMALLOC: | 2250 | case DMA_MEM_TYPE_KMALLOC: |
@@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | |||
2276 | printk(KERN_ERR | 2281 | printk(KERN_ERR |
2277 | "%s: Unsupported memory type: %d\n", | 2282 | "%s: Unsupported memory type: %d\n", |
2278 | __func__, region->memType); | 2283 | __func__, region->memType); |
2279 | return -EINVAL; | 2284 | rc = -EINVAL; |
2285 | goto out; | ||
2280 | } | 2286 | } |
2281 | } | 2287 | } |
2282 | 2288 | ||
@@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | |||
2314 | memMap->numRegionsUsed = 0; | 2320 | memMap->numRegionsUsed = 0; |
2315 | memMap->inUse = 0; | 2321 | memMap->inUse = 0; |
2316 | 2322 | ||
2323 | out: | ||
2317 | up(&memMap->lock); | 2324 | up(&memMap->lock); |
2318 | 2325 | ||
2319 | return 0; | 2326 | return rc; |
2320 | } | 2327 | } |
2321 | 2328 | ||
2322 | EXPORT_SYMBOL(dma_unmap); | 2329 | EXPORT_SYMBOL(dma_unmap); |
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index cc377ae8c428..cf547ad7ebd4 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | 26 | ||
27 | /************************************************************************* | 27 | /************************************************************************* |
28 | * GPIO handling for EP93xx | 28 | * Interrupt handling for EP93xx on-chip GPIOs |
29 | *************************************************************************/ | 29 | *************************************************************************/ |
30 | static unsigned char gpio_int_unmasked[3]; | 30 | static unsigned char gpio_int_unmasked[3]; |
31 | static unsigned char gpio_int_enabled[3]; | 31 | static unsigned char gpio_int_enabled[3]; |
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; | |||
40 | static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; | 40 | static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; |
41 | static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; | 41 | static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; |
42 | 42 | ||
43 | void ep93xx_gpio_update_int_params(unsigned port) | 43 | static void ep93xx_gpio_update_int_params(unsigned port) |
44 | { | 44 | { |
45 | BUG_ON(port > 2); | 45 | BUG_ON(port > 2); |
46 | 46 | ||
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port) | |||
56 | EP93XX_GPIO_REG(int_en_register_offset[port])); | 56 | EP93XX_GPIO_REG(int_en_register_offset[port])); |
57 | } | 57 | } |
58 | 58 | ||
59 | void ep93xx_gpio_int_mask(unsigned line) | 59 | static inline void ep93xx_gpio_int_mask(unsigned line) |
60 | { | 60 | { |
61 | gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); | 61 | gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); |
62 | } | 62 | } |
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 3872af1cf2c3..170f68e46dd5 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig | |||
@@ -62,6 +62,15 @@ config MACH_MX31_3DS | |||
62 | Include support for MX31PDK (3DS) platform. This includes specific | 62 | Include support for MX31PDK (3DS) platform. This includes specific |
63 | configurations for the board and its peripherals. | 63 | configurations for the board and its peripherals. |
64 | 64 | ||
65 | config MACH_MX31_3DS_MXC_NAND_USE_BBT | ||
66 | bool "Make the MXC NAND driver use the in flash Bad Block Table" | ||
67 | depends on MACH_MX31_3DS | ||
68 | depends on MTD_NAND_MXC | ||
69 | help | ||
70 | Enable this if you want that the MXC NAND driver uses the in flash | ||
71 | Bad Block Table to know what blocks are bad instead of scanning the | ||
72 | entire flash looking for bad block markers. | ||
73 | |||
65 | config MACH_MX31MOBOARD | 74 | config MACH_MX31MOBOARD |
66 | bool "Support mx31moboard platforms (EPFL Mobots group)" | 75 | bool "Support mx31moboard platforms (EPFL Mobots group)" |
67 | select ARCH_MX31 | 76 | select ARCH_MX31 |
@@ -95,6 +104,7 @@ config MACH_PCM043 | |||
95 | config MACH_ARMADILLO5X0 | 104 | config MACH_ARMADILLO5X0 |
96 | bool "Support Atmark Armadillo-500 Development Base Board" | 105 | bool "Support Atmark Armadillo-500 Development Base Board" |
97 | select ARCH_MX31 | 106 | select ARCH_MX31 |
107 | select MXC_ULPI if USB_ULPI | ||
98 | help | 108 | help |
99 | Include support for Atmark Armadillo-500 platform. This includes | 109 | Include support for Atmark Armadillo-500 platform. This includes |
100 | specific configurations for the board and its peripherals. | 110 | specific configurations for the board and its peripherals. |
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c index 80dba9966b5e..9a9eb6de6127 100644 --- a/arch/arm/mach-mx3/clock-imx31.c +++ b/arch/arm/mach-mx3/clock-imx31.c | |||
@@ -468,6 +468,7 @@ static struct clk ahb_clk = { | |||
468 | } | 468 | } |
469 | 469 | ||
470 | DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | 470 | DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); |
471 | DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); | ||
471 | 472 | ||
472 | DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); | 473 | DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); |
473 | DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); | 474 | DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); |
@@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); | |||
490 | DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); | 491 | DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); |
491 | DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); | 492 | DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); |
492 | DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); | 493 | DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); |
493 | DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); | 494 | DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); |
494 | DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); | 495 | DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); |
495 | DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); | 496 | DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); |
496 | DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); | 497 | DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); |
@@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk) | |||
514 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); | 515 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); |
515 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | 516 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); |
516 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | 517 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); |
517 | DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); | ||
518 | 518 | ||
519 | #define _REGISTER_CLOCK(d, n, c) \ | 519 | #define _REGISTER_CLOCK(d, n, c) \ |
520 | { \ | 520 | { \ |
@@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = { | |||
572 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | 572 | _REGISTER_CLOCK(NULL, "iim", iim_clk) |
573 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) | 573 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) |
574 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) | 574 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) |
575 | _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk) | ||
576 | }; | 575 | }; |
577 | 576 | ||
578 | int __init mx31_clocks_init(unsigned long fref) | 577 | int __init mx31_clocks_init(unsigned long fref) |
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 6adb586515ea..f8911154a9fa 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c | |||
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = { | |||
575 | .resource = imx_ssi_resources1, | 575 | .resource = imx_ssi_resources1, |
576 | }; | 576 | }; |
577 | 577 | ||
578 | static int mx3_devices_init(void) | 578 | static struct resource imx_wdt_resources[] = { |
579 | { | ||
580 | .flags = IORESOURCE_MEM, | ||
581 | }, | ||
582 | }; | ||
583 | |||
584 | struct platform_device imx_wdt_device0 = { | ||
585 | .name = "imx-wdt", | ||
586 | .id = 0, | ||
587 | .num_resources = ARRAY_SIZE(imx_wdt_resources), | ||
588 | .resource = imx_wdt_resources, | ||
589 | }; | ||
590 | |||
591 | static int __init mx3_devices_init(void) | ||
579 | { | 592 | { |
580 | if (cpu_is_mx31()) { | 593 | if (cpu_is_mx31()) { |
581 | mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; | 594 | mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; |
582 | mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; | 595 | mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; |
596 | imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR; | ||
597 | imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff; | ||
583 | mxc_register_device(&mxc_rnga_device, NULL); | 598 | mxc_register_device(&mxc_rnga_device, NULL); |
584 | } | 599 | } |
585 | if (cpu_is_mx35()) { | 600 | if (cpu_is_mx35()) { |
@@ -597,6 +612,8 @@ static int mx3_devices_init(void) | |||
597 | imx_ssi_resources0[1].end = MX35_INT_SSI1; | 612 | imx_ssi_resources0[1].end = MX35_INT_SSI1; |
598 | imx_ssi_resources1[1].start = MX35_INT_SSI2; | 613 | imx_ssi_resources1[1].start = MX35_INT_SSI2; |
599 | imx_ssi_resources1[1].end = MX35_INT_SSI2; | 614 | imx_ssi_resources1[1].end = MX35_INT_SSI2; |
615 | imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; | ||
616 | imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; | ||
600 | } | 617 | } |
601 | 618 | ||
602 | return 0; | 619 | return 0; |
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index 42cf175eac6b..4f77eb501274 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h | |||
@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1; | |||
25 | extern struct platform_device mxc_spi_device2; | 25 | extern struct platform_device mxc_spi_device2; |
26 | extern struct platform_device imx_ssi_device0; | 26 | extern struct platform_device imx_ssi_device0; |
27 | extern struct platform_device imx_ssi_device1; | 27 | extern struct platform_device imx_ssi_device1; |
28 | 28 | extern struct platform_device imx_ssi_device1; | |
29 | extern struct platform_device imx_wdt_device0; | ||
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c index 3d72b0b89705..5f72ec91af2d 100644 --- a/arch/arm/mach-mx3/mach-armadillo5x0.c +++ b/arch/arm/mach-mx3/mach-armadillo5x0.c | |||
@@ -36,6 +36,9 @@ | |||
36 | #include <linux/input.h> | 36 | #include <linux/input.h> |
37 | #include <linux/gpio_keys.h> | 37 | #include <linux/gpio_keys.h> |
38 | #include <linux/i2c.h> | 38 | #include <linux/i2c.h> |
39 | #include <linux/usb/otg.h> | ||
40 | #include <linux/usb/ulpi.h> | ||
41 | #include <linux/delay.h> | ||
39 | 42 | ||
40 | #include <mach/hardware.h> | 43 | #include <mach/hardware.h> |
41 | #include <asm/mach-types.h> | 44 | #include <asm/mach-types.h> |
@@ -52,6 +55,8 @@ | |||
52 | #include <mach/ipu.h> | 55 | #include <mach/ipu.h> |
53 | #include <mach/mx3fb.h> | 56 | #include <mach/mx3fb.h> |
54 | #include <mach/mxc_nand.h> | 57 | #include <mach/mxc_nand.h> |
58 | #include <mach/mxc_ehci.h> | ||
59 | #include <mach/ulpi.h> | ||
55 | 60 | ||
56 | #include "devices.h" | 61 | #include "devices.h" |
57 | #include "crm_regs.h" | 62 | #include "crm_regs.h" |
@@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = { | |||
103 | /* I2C2 */ | 108 | /* I2C2 */ |
104 | MX31_PIN_CSPI2_MOSI__SCL, | 109 | MX31_PIN_CSPI2_MOSI__SCL, |
105 | MX31_PIN_CSPI2_MISO__SDA, | 110 | MX31_PIN_CSPI2_MISO__SDA, |
111 | /* OTG */ | ||
112 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
113 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
114 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
115 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
116 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
117 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
118 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
119 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
120 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, | ||
121 | MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
122 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, | ||
123 | MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
124 | /* USB host 2 */ | ||
125 | IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), | ||
126 | IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), | ||
127 | IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), | ||
128 | IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), | ||
129 | IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), | ||
130 | IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), | ||
131 | IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), | ||
132 | IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), | ||
133 | IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), | ||
134 | IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), | ||
135 | IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), | ||
136 | IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), | ||
106 | }; | 137 | }; |
107 | 138 | ||
139 | /* USB */ | ||
140 | #if defined(CONFIG_USB_ULPI) | ||
141 | |||
142 | #define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) | ||
143 | #define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) | ||
144 | #define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) | ||
145 | |||
146 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
147 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
148 | |||
149 | static int usbotg_init(struct platform_device *pdev) | ||
150 | { | ||
151 | int err; | ||
152 | |||
153 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); | ||
154 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); | ||
155 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); | ||
156 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); | ||
157 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); | ||
158 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); | ||
159 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); | ||
160 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); | ||
161 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); | ||
162 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); | ||
163 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); | ||
164 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); | ||
165 | |||
166 | /* Chip already enabled by hardware */ | ||
167 | /* OTG phy reset*/ | ||
168 | err = gpio_request(OTG_RESET, "USB-OTG-RESET"); | ||
169 | if (err) { | ||
170 | pr_err("Failed to request the usb otg reset gpio\n"); | ||
171 | return err; | ||
172 | } | ||
173 | |||
174 | err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); | ||
175 | if (err) { | ||
176 | pr_err("Failed to reset the usb otg phy\n"); | ||
177 | goto otg_free_reset; | ||
178 | } | ||
179 | |||
180 | gpio_set_value(OTG_RESET, 0/*LOW*/); | ||
181 | mdelay(5); | ||
182 | gpio_set_value(OTG_RESET, 1/*HIGH*/); | ||
183 | |||
184 | return 0; | ||
185 | |||
186 | otg_free_reset: | ||
187 | gpio_free(OTG_RESET); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | static int usbh2_init(struct platform_device *pdev) | ||
192 | { | ||
193 | int err; | ||
194 | |||
195 | mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); | ||
196 | mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); | ||
197 | mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); | ||
198 | mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); | ||
199 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); | ||
200 | mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); | ||
201 | mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); | ||
202 | mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); | ||
203 | mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); | ||
204 | mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); | ||
205 | mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); | ||
206 | mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); | ||
207 | |||
208 | mxc_iomux_set_gpr(MUX_PGP_UH2, true); | ||
209 | |||
210 | |||
211 | /* Enable the chip */ | ||
212 | err = gpio_request(USBH2_CS, "USB-H2-CS"); | ||
213 | if (err) { | ||
214 | pr_err("Failed to request the usb host 2 CS gpio\n"); | ||
215 | return err; | ||
216 | } | ||
217 | |||
218 | err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); | ||
219 | if (err) { | ||
220 | pr_err("Failed to drive the usb host 2 CS gpio\n"); | ||
221 | goto h2_free_cs; | ||
222 | } | ||
223 | |||
224 | /* H2 phy reset*/ | ||
225 | err = gpio_request(USBH2_RESET, "USB-H2-RESET"); | ||
226 | if (err) { | ||
227 | pr_err("Failed to request the usb host 2 reset gpio\n"); | ||
228 | goto h2_free_cs; | ||
229 | } | ||
230 | |||
231 | err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); | ||
232 | if (err) { | ||
233 | pr_err("Failed to reset the usb host 2 phy\n"); | ||
234 | goto h2_free_reset; | ||
235 | } | ||
236 | |||
237 | gpio_set_value(USBH2_RESET, 0/*LOW*/); | ||
238 | mdelay(5); | ||
239 | gpio_set_value(USBH2_RESET, 1/*HIGH*/); | ||
240 | |||
241 | return 0; | ||
242 | |||
243 | h2_free_reset: | ||
244 | gpio_free(USBH2_RESET); | ||
245 | h2_free_cs: | ||
246 | gpio_free(USBH2_CS); | ||
247 | return err; | ||
248 | } | ||
249 | |||
250 | static struct mxc_usbh_platform_data usbotg_pdata = { | ||
251 | .init = usbotg_init, | ||
252 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
253 | .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, | ||
254 | }; | ||
255 | |||
256 | static struct mxc_usbh_platform_data usbh2_pdata = { | ||
257 | .init = usbh2_init, | ||
258 | .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, | ||
259 | .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, | ||
260 | }; | ||
261 | #endif /* CONFIG_USB_ULPI */ | ||
262 | |||
108 | /* RTC over I2C*/ | 263 | /* RTC over I2C*/ |
109 | #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) | 264 | #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) |
110 | 265 | ||
@@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void) | |||
393 | if (armadillo5x0_i2c_rtc.irq == 0) | 548 | if (armadillo5x0_i2c_rtc.irq == 0) |
394 | pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); | 549 | pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); |
395 | i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); | 550 | i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); |
551 | |||
552 | /* USB */ | ||
553 | #if defined(CONFIG_USB_ULPI) | ||
554 | usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | ||
555 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | ||
556 | usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, | ||
557 | USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); | ||
558 | |||
559 | mxc_register_device(&mxc_otg_host, &usbotg_pdata); | ||
560 | mxc_register_device(&mxc_usbh2, &usbh2_pdata); | ||
561 | #endif | ||
396 | } | 562 | } |
397 | 563 | ||
398 | static void __init armadillo5x0_timer_init(void) | 564 | static void __init armadillo5x0_timer_init(void) |
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index b88c18ad7698..f54af1e29ca4 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/smsc911x.h> | 24 | #include <linux/smsc911x.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/mfd/mc13783.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/regulator/machine.h> | ||
26 | 29 | ||
27 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
28 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
@@ -31,26 +34,96 @@ | |||
31 | #include <asm/memory.h> | 34 | #include <asm/memory.h> |
32 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
33 | #include <mach/common.h> | 36 | #include <mach/common.h> |
34 | #include <mach/board-mx31pdk.h> | 37 | #include <mach/board-mx31_3ds.h> |
35 | #include <mach/imx-uart.h> | 38 | #include <mach/imx-uart.h> |
36 | #include <mach/iomux-mx3.h> | 39 | #include <mach/iomux-mx3.h> |
40 | #include <mach/mxc_nand.h> | ||
41 | #include <mach/spi.h> | ||
37 | #include "devices.h" | 42 | #include "devices.h" |
38 | 43 | ||
39 | /*! | 44 | /*! |
40 | * @file mx31pdk.c | 45 | * @file mx31_3ds.c |
41 | * | 46 | * |
42 | * @brief This file contains the board-specific initialization routines. | 47 | * @brief This file contains the board-specific initialization routines. |
43 | * | 48 | * |
44 | * @ingroup System | 49 | * @ingroup System |
45 | */ | 50 | */ |
46 | 51 | ||
47 | static int mx31pdk_pins[] = { | 52 | static int mx31_3ds_pins[] = { |
48 | /* UART1 */ | 53 | /* UART1 */ |
49 | MX31_PIN_CTS1__CTS1, | 54 | MX31_PIN_CTS1__CTS1, |
50 | MX31_PIN_RTS1__RTS1, | 55 | MX31_PIN_RTS1__RTS1, |
51 | MX31_PIN_TXD1__TXD1, | 56 | MX31_PIN_TXD1__TXD1, |
52 | MX31_PIN_RXD1__RXD1, | 57 | MX31_PIN_RXD1__RXD1, |
53 | IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), | 58 | IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), |
59 | /* SPI 1 */ | ||
60 | MX31_PIN_CSPI2_SCLK__SCLK, | ||
61 | MX31_PIN_CSPI2_MOSI__MOSI, | ||
62 | MX31_PIN_CSPI2_MISO__MISO, | ||
63 | MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, | ||
64 | MX31_PIN_CSPI2_SS0__SS0, | ||
65 | MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ | ||
66 | /* MC13783 IRQ */ | ||
67 | IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), | ||
68 | }; | ||
69 | |||
70 | /* Regulators */ | ||
71 | static struct regulator_init_data pwgtx_init = { | ||
72 | .constraints = { | ||
73 | .boot_on = 1, | ||
74 | .always_on = 1, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static struct mc13783_regulator_init_data mx31_3ds_regulators[] = { | ||
79 | { | ||
80 | .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */ | ||
81 | .init_data = &pwgtx_init, | ||
82 | }, { | ||
83 | .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */ | ||
84 | .init_data = &pwgtx_init, | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | /* MC13783 */ | ||
89 | static struct mc13783_platform_data mc13783_pdata __initdata = { | ||
90 | .regulators = mx31_3ds_regulators, | ||
91 | .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), | ||
92 | .flags = MC13783_USE_REGULATOR, | ||
93 | }; | ||
94 | |||
95 | /* SPI */ | ||
96 | static int spi1_internal_chipselect[] = { | ||
97 | MXC_SPI_CS(0), | ||
98 | MXC_SPI_CS(2), | ||
99 | }; | ||
100 | |||
101 | static struct spi_imx_master spi1_pdata = { | ||
102 | .chipselect = spi1_internal_chipselect, | ||
103 | .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), | ||
104 | }; | ||
105 | |||
106 | static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { | ||
107 | { | ||
108 | .modalias = "mc13783", | ||
109 | .max_speed_hz = 1000000, | ||
110 | .bus_num = 1, | ||
111 | .chip_select = 1, /* SS2 */ | ||
112 | .platform_data = &mc13783_pdata, | ||
113 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
114 | .mode = SPI_CS_HIGH, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | /* | ||
119 | * NAND Flash | ||
120 | */ | ||
121 | static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = { | ||
122 | .width = 1, | ||
123 | .hw_ecc = 1, | ||
124 | #ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT | ||
125 | .flash_bbt = 1, | ||
126 | #endif | ||
54 | }; | 127 | }; |
55 | 128 | ||
56 | static struct imxuart_platform_data uart_pdata = { | 129 | static struct imxuart_platform_data uart_pdata = { |
@@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = { | |||
95 | * LEDs, switches, interrupts for Ethernet. | 168 | * LEDs, switches, interrupts for Ethernet. |
96 | */ | 169 | */ |
97 | 170 | ||
98 | static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc) | 171 | static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc) |
99 | { | 172 | { |
100 | uint32_t imr_val; | 173 | uint32_t imr_val; |
101 | uint32_t int_valid; | 174 | uint32_t int_valid; |
@@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = { | |||
163 | .unmask = expio_unmask_irq, | 236 | .unmask = expio_unmask_irq, |
164 | }; | 237 | }; |
165 | 238 | ||
166 | static int __init mx31pdk_init_expio(void) | 239 | static int __init mx31_3ds_init_expio(void) |
167 | { | 240 | { |
168 | int i; | 241 | int i; |
169 | int ret; | 242 | int ret; |
@@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void) | |||
176 | return -ENODEV; | 249 | return -ENODEV; |
177 | } | 250 | } |
178 | 251 | ||
179 | pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n", | 252 | pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n", |
180 | __raw_readw(CPLD_CODE_VER_REG)); | 253 | __raw_readw(CPLD_CODE_VER_REG)); |
181 | 254 | ||
182 | /* | 255 | /* |
@@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void) | |||
201 | set_irq_flags(i, IRQF_VALID); | 274 | set_irq_flags(i, IRQF_VALID); |
202 | } | 275 | } |
203 | set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW); | 276 | set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW); |
204 | set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler); | 277 | set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler); |
205 | 278 | ||
206 | return 0; | 279 | return 0; |
207 | } | 280 | } |
@@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void) | |||
209 | /* | 282 | /* |
210 | * This structure defines the MX31 memory map. | 283 | * This structure defines the MX31 memory map. |
211 | */ | 284 | */ |
212 | static struct map_desc mx31pdk_io_desc[] __initdata = { | 285 | static struct map_desc mx31_3ds_io_desc[] __initdata = { |
213 | { | 286 | { |
214 | .virtual = MX31_CS5_BASE_ADDR_VIRT, | 287 | .virtual = MX31_CS5_BASE_ADDR_VIRT, |
215 | .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), | 288 | .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), |
@@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = { | |||
221 | /* | 294 | /* |
222 | * Set up static virtual mappings. | 295 | * Set up static virtual mappings. |
223 | */ | 296 | */ |
224 | static void __init mx31pdk_map_io(void) | 297 | static void __init mx31_3ds_map_io(void) |
225 | { | 298 | { |
226 | mx31_map_io(); | 299 | mx31_map_io(); |
227 | iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc)); | 300 | iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc)); |
228 | } | 301 | } |
229 | 302 | ||
230 | /*! | 303 | /*! |
@@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void) | |||
232 | */ | 305 | */ |
233 | static void __init mxc_board_init(void) | 306 | static void __init mxc_board_init(void) |
234 | { | 307 | { |
235 | mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins), | 308 | mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), |
236 | "mx31pdk"); | 309 | "mx31_3ds"); |
237 | 310 | ||
238 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 311 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
312 | mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); | ||
313 | |||
314 | mxc_register_device(&mxc_spi_device1, &spi1_pdata); | ||
315 | spi_register_board_info(mx31_3ds_spi_devs, | ||
316 | ARRAY_SIZE(mx31_3ds_spi_devs)); | ||
239 | 317 | ||
240 | if (!mx31pdk_init_expio()) | 318 | if (!mx31_3ds_init_expio()) |
241 | platform_device_register(&smsc911x_device); | 319 | platform_device_register(&smsc911x_device); |
242 | } | 320 | } |
243 | 321 | ||
244 | static void __init mx31pdk_timer_init(void) | 322 | static void __init mx31_3ds_timer_init(void) |
245 | { | 323 | { |
246 | mx31_clocks_init(26000000); | 324 | mx31_clocks_init(26000000); |
247 | } | 325 | } |
248 | 326 | ||
249 | static struct sys_timer mx31pdk_timer = { | 327 | static struct sys_timer mx31_3ds_timer = { |
250 | .init = mx31pdk_timer_init, | 328 | .init = mx31_3ds_timer_init, |
251 | }; | 329 | }; |
252 | 330 | ||
253 | /* | 331 | /* |
254 | * The following uses standard kernel macros defined in arch.h in order to | 332 | * The following uses standard kernel macros defined in arch.h in order to |
255 | * initialize __mach_desc_MX31PDK data structure. | 333 | * initialize __mach_desc_MX31_3DS data structure. |
256 | */ | 334 | */ |
257 | MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") | 335 | MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") |
258 | /* Maintainer: Freescale Semiconductor, Inc. */ | 336 | /* Maintainer: Freescale Semiconductor, Inc. */ |
259 | .phys_io = MX31_AIPS1_BASE_ADDR, | 337 | .phys_io = MX31_AIPS1_BASE_ADDR, |
260 | .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, | 338 | .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, |
261 | .boot_params = MX3x_PHYS_OFFSET + 0x100, | 339 | .boot_params = MX3x_PHYS_OFFSET + 0x100, |
262 | .map_io = mx31pdk_map_io, | 340 | .map_io = mx31_3ds_map_io, |
263 | .init_irq = mx31_init_irq, | 341 | .init_irq = mx31_init_irq, |
264 | .init_machine = mxc_board_init, | 342 | .init_machine = mxc_board_init, |
265 | .timer = &mx31pdk_timer, | 343 | .timer = &mx31_3ds_timer, |
266 | MACHINE_END | 344 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 034ec8190065..2df1ec55a97e 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/can/platform/sja1000.h> | 35 | #include <linux/can/platform/sja1000.h> |
36 | #include <linux/usb/otg.h> | 36 | #include <linux/usb/otg.h> |
37 | #include <linux/usb/ulpi.h> | 37 | #include <linux/usb/ulpi.h> |
38 | #include <linux/fsl_devices.h> | ||
39 | #include <linux/gfp.h> | 38 | #include <linux/gfp.h> |
40 | 39 | ||
41 | #include <media/soc_camera.h> | 40 | #include <media/soc_camera.h> |
diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index ccd874225c3b..093c595ca581 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/leds.h> | 31 | #include <linux/leds.h> |
33 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
34 | 33 | ||
@@ -206,5 +205,6 @@ void __init mx31lite_db_init(void) | |||
206 | mxc_register_device(&mxcsdhc_device0, &mmc_pdata); | 205 | mxc_register_device(&mxcsdhc_device0, &mmc_pdata); |
207 | mxc_register_device(&mxc_spi_device0, &spi0_pdata); | 206 | mxc_register_device(&mxc_spi_device0, &spi0_pdata); |
208 | platform_device_register(&litekit_led_device); | 207 | platform_device_register(&litekit_led_device); |
208 | mxc_register_device(&imx_wdt_device0, NULL); | ||
209 | } | 209 | } |
210 | 210 | ||
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index be90c03101cd..8f85f73b83a8 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c | |||
@@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, | |||
757 | 757 | ||
758 | /* GPT */ | 758 | /* GPT */ |
759 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, | 759 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, |
760 | NULL, NULL, &ipg_perclk, NULL); | 760 | NULL, NULL, &ipg_clk, NULL); |
761 | DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, | 761 | DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, |
762 | NULL, NULL, &ipg_clk, NULL); | 762 | NULL, NULL, &ipg_clk, NULL); |
763 | 763 | ||
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index 41c769f08c4d..2d37785e3857 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c | |||
@@ -14,9 +14,62 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/module.h> | ||
17 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
19 | 20 | ||
21 | static int cpu_silicon_rev = -1; | ||
22 | |||
23 | #define SI_REV 0x48 | ||
24 | |||
25 | static void query_silicon_parameter(void) | ||
26 | { | ||
27 | void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE); | ||
28 | u32 rev; | ||
29 | |||
30 | if (!rom) { | ||
31 | cpu_silicon_rev = -EINVAL; | ||
32 | return; | ||
33 | } | ||
34 | |||
35 | rev = readl(rom + SI_REV); | ||
36 | switch (rev) { | ||
37 | case 0x1: | ||
38 | cpu_silicon_rev = MX51_CHIP_REV_1_0; | ||
39 | break; | ||
40 | case 0x2: | ||
41 | cpu_silicon_rev = MX51_CHIP_REV_1_1; | ||
42 | break; | ||
43 | case 0x10: | ||
44 | cpu_silicon_rev = MX51_CHIP_REV_2_0; | ||
45 | break; | ||
46 | case 0x20: | ||
47 | cpu_silicon_rev = MX51_CHIP_REV_3_0; | ||
48 | break; | ||
49 | default: | ||
50 | cpu_silicon_rev = 0; | ||
51 | } | ||
52 | |||
53 | iounmap(rom); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Returns: | ||
58 | * the silicon revision of the cpu | ||
59 | * -EINVAL - not a mx51 | ||
60 | */ | ||
61 | int mx51_revision(void) | ||
62 | { | ||
63 | if (!cpu_is_mx51()) | ||
64 | return -EINVAL; | ||
65 | |||
66 | if (cpu_silicon_rev == -1) | ||
67 | query_silicon_parameter(); | ||
68 | |||
69 | return cpu_silicon_rev; | ||
70 | } | ||
71 | EXPORT_SYMBOL(mx51_revision); | ||
72 | |||
20 | static int __init post_cpu_init(void) | 73 | static int __init post_cpu_init(void) |
21 | { | 74 | { |
22 | unsigned int reg; | 75 | unsigned int reg; |
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index c21e18be7af8..b7677ef80cc4 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c | |||
@@ -35,11 +35,6 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
35 | .length = MX51_DEBUG_SIZE, | 35 | .length = MX51_DEBUG_SIZE, |
36 | .type = MT_DEVICE | 36 | .type = MT_DEVICE |
37 | }, { | 37 | }, { |
38 | .virtual = MX51_TZIC_BASE_ADDR_VIRT, | ||
39 | .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR), | ||
40 | .length = MX51_TZIC_SIZE, | ||
41 | .type = MT_DEVICE | ||
42 | }, { | ||
43 | .virtual = MX51_AIPS1_BASE_ADDR_VIRT, | 38 | .virtual = MX51_AIPS1_BASE_ADDR_VIRT, |
44 | .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR), | 39 | .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR), |
45 | .length = MX51_AIPS1_SIZE, | 40 | .length = MX51_AIPS1_SIZE, |
@@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
54 | .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR), | 49 | .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR), |
55 | .length = MX51_AIPS2_SIZE, | 50 | .length = MX51_AIPS2_SIZE, |
56 | .type = MT_DEVICE | 51 | .type = MT_DEVICE |
57 | }, { | ||
58 | .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT, | ||
59 | .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR), | ||
60 | .length = MX51_NFC_AXI_SIZE, | ||
61 | .type = MT_DEVICE | ||
62 | }, | 52 | }, |
63 | }; | 53 | }; |
64 | 54 | ||
@@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
69 | */ | 59 | */ |
70 | void __init mx51_map_io(void) | 60 | void __init mx51_map_io(void) |
71 | { | 61 | { |
72 | u32 tzic_addr; | ||
73 | |||
74 | if (mx51_revision() < MX51_CHIP_REV_2_0) | ||
75 | tzic_addr = 0x8FFFC000; | ||
76 | else | ||
77 | tzic_addr = 0xE0003000; | ||
78 | mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr); | ||
79 | |||
80 | mxc_set_cpu_type(MXC_CPU_MX51); | 62 | mxc_set_cpu_type(MXC_CPU_MX51); |
81 | mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); | 63 | mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); |
82 | mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR)); | 64 | mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR)); |
@@ -85,5 +67,17 @@ void __init mx51_map_io(void) | |||
85 | 67 | ||
86 | void __init mx51_init_irq(void) | 68 | void __init mx51_init_irq(void) |
87 | { | 69 | { |
88 | tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR)); | 70 | unsigned long tzic_addr; |
71 | void __iomem *tzic_virt; | ||
72 | |||
73 | if (mx51_revision() < MX51_CHIP_REV_2_0) | ||
74 | tzic_addr = MX51_TZIC_BASE_ADDR_TO1; | ||
75 | else | ||
76 | tzic_addr = MX51_TZIC_BASE_ADDR; | ||
77 | |||
78 | tzic_virt = ioremap(tzic_addr, SZ_16K); | ||
79 | if (!tzic_virt) | ||
80 | panic("unable to map TZIC interrupt controller\n"); | ||
81 | |||
82 | tzic_init_irq(tzic_virt); | ||
89 | } | 83 | } |
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 8bca4dea6dfa..f55fa1044f72 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c | |||
@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, | |||
41 | kfrom = kmap_atomic(from, KM_USER0); | 41 | kfrom = kmap_atomic(from, KM_USER0); |
42 | kto = kmap_atomic(to, KM_USER1); | 42 | kto = kmap_atomic(to, KM_USER1); |
43 | copy_page(kto, kfrom); | 43 | copy_page(kto, kfrom); |
44 | #ifdef CONFIG_HIGHMEM | 44 | __cpuc_flush_dcache_area(kto, PAGE_SIZE); |
45 | /* | ||
46 | * kmap_atomic() doesn't set the page virtual address, and | ||
47 | * kunmap_atomic() takes care of cache flushing already. | ||
48 | */ | ||
49 | if (page_address(to) != NULL) | ||
50 | #endif | ||
51 | __cpuc_flush_dcache_area(kto, PAGE_SIZE); | ||
52 | kunmap_atomic(kto, KM_USER1); | 45 | kunmap_atomic(kto, KM_USER1); |
53 | kunmap_atomic(kfrom, KM_USER0); | 46 | kunmap_atomic(kfrom, KM_USER0); |
54 | } | 47 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1351edc0b26f..13fa536d82e6 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, | |||
464 | vaddr += offset; | 464 | vaddr += offset; |
465 | op(vaddr, len, dir); | 465 | op(vaddr, len, dir); |
466 | kunmap_high(page); | 466 | kunmap_high(page); |
467 | } else if (cache_is_vipt()) { | ||
468 | pte_t saved_pte; | ||
469 | vaddr = kmap_high_l1_vipt(page, &saved_pte); | ||
470 | op(vaddr + offset, len, dir); | ||
471 | kunmap_high_l1_vipt(page, saved_pte); | ||
467 | } | 472 | } |
468 | } else { | 473 | } else { |
469 | vaddr = page_address(page) + offset; | 474 | vaddr = page_address(page) + offset; |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index e34f095e2090..c6844cb9b508 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/cachetype.h> | 15 | #include <asm/cachetype.h> |
16 | #include <asm/highmem.h> | ||
16 | #include <asm/smp_plat.h> | 17 | #include <asm/smp_plat.h> |
17 | #include <asm/system.h> | 18 | #include <asm/system.h> |
18 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | |||
152 | 153 | ||
153 | void __flush_dcache_page(struct address_space *mapping, struct page *page) | 154 | void __flush_dcache_page(struct address_space *mapping, struct page *page) |
154 | { | 155 | { |
155 | void *addr = page_address(page); | ||
156 | |||
157 | /* | 156 | /* |
158 | * Writeback any data associated with the kernel mapping of this | 157 | * Writeback any data associated with the kernel mapping of this |
159 | * page. This ensures that data in the physical page is mutually | 158 | * page. This ensures that data in the physical page is mutually |
160 | * coherent with the kernels mapping. | 159 | * coherent with the kernels mapping. |
161 | */ | 160 | */ |
162 | #ifdef CONFIG_HIGHMEM | 161 | if (!PageHighMem(page)) { |
163 | /* | 162 | __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); |
164 | * kmap_atomic() doesn't set the page virtual address, and | 163 | } else { |
165 | * kunmap_atomic() takes care of cache flushing already. | 164 | void *addr = kmap_high_get(page); |
166 | */ | 165 | if (addr) { |
167 | if (addr) | 166 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); |
168 | #endif | 167 | kunmap_high(page); |
169 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | 168 | } else if (cache_is_vipt()) { |
169 | pte_t saved_pte; | ||
170 | addr = kmap_high_l1_vipt(page, &saved_pte); | ||
171 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | ||
172 | kunmap_high_l1_vipt(page, saved_pte); | ||
173 | } | ||
174 | } | ||
170 | 175 | ||
171 | /* | 176 | /* |
172 | * If this is a page cache page, and we have an aliasing VIPT cache, | 177 | * If this is a page cache page, and we have an aliasing VIPT cache, |
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 2be1ec7c1b41..77b030f5ec09 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c | |||
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type) | |||
79 | unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); | 79 | unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); |
80 | 80 | ||
81 | if (kvaddr >= (void *)FIXADDR_START) { | 81 | if (kvaddr >= (void *)FIXADDR_START) { |
82 | __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); | 82 | if (cache_is_vivt()) |
83 | __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); | ||
83 | #ifdef CONFIG_DEBUG_HIGHMEM | 84 | #ifdef CONFIG_DEBUG_HIGHMEM |
84 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | 85 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); |
85 | set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); | 86 | set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); |
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr) | |||
124 | pte = TOP_PTE(vaddr); | 125 | pte = TOP_PTE(vaddr); |
125 | return pte_page(*pte); | 126 | return pte_page(*pte); |
126 | } | 127 | } |
128 | |||
129 | #ifdef CONFIG_CPU_CACHE_VIPT | ||
130 | |||
131 | #include <linux/percpu.h> | ||
132 | |||
133 | /* | ||
134 | * The VIVT cache of a highmem page is always flushed before the page | ||
135 | * is unmapped. Hence unmapped highmem pages need no cache maintenance | ||
136 | * in that case. | ||
137 | * | ||
138 | * However unmapped pages may still be cached with a VIPT cache, and | ||
139 | * it is not possible to perform cache maintenance on them using physical | ||
140 | * addresses unfortunately. So we have no choice but to set up a temporary | ||
141 | * virtual mapping for that purpose. | ||
142 | * | ||
143 | * Yet this VIPT cache maintenance may be triggered from DMA support | ||
144 | * functions which are possibly called from interrupt context. As we don't | ||
145 | * want to keep interrupt disabled all the time when such maintenance is | ||
146 | * taking place, we therefore allow for some reentrancy by preserving and | ||
147 | * restoring the previous fixmap entry before the interrupted context is | ||
148 | * resumed. If the reentrancy depth is 0 then there is no need to restore | ||
149 | * the previous fixmap, and leaving the current one in place allow it to | ||
150 | * be reused the next time without a TLB flush (common with DMA). | ||
151 | */ | ||
152 | |||
153 | static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth); | ||
154 | |||
155 | void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte) | ||
156 | { | ||
157 | unsigned int idx, cpu = smp_processor_id(); | ||
158 | int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); | ||
159 | unsigned long vaddr, flags; | ||
160 | pte_t pte, *ptep; | ||
161 | |||
162 | idx = KM_L1_CACHE + KM_TYPE_NR * cpu; | ||
163 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
164 | ptep = TOP_PTE(vaddr); | ||
165 | pte = mk_pte(page, kmap_prot); | ||
166 | |||
167 | if (!in_interrupt()) | ||
168 | preempt_disable(); | ||
169 | |||
170 | raw_local_irq_save(flags); | ||
171 | (*depth)++; | ||
172 | if (pte_val(*ptep) == pte_val(pte)) { | ||
173 | *saved_pte = pte; | ||
174 | } else { | ||
175 | *saved_pte = *ptep; | ||
176 | set_pte_ext(ptep, pte, 0); | ||
177 | local_flush_tlb_kernel_page(vaddr); | ||
178 | } | ||
179 | raw_local_irq_restore(flags); | ||
180 | |||
181 | return (void *)vaddr; | ||
182 | } | ||
183 | |||
184 | void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte) | ||
185 | { | ||
186 | unsigned int idx, cpu = smp_processor_id(); | ||
187 | int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); | ||
188 | unsigned long vaddr, flags; | ||
189 | pte_t pte, *ptep; | ||
190 | |||
191 | idx = KM_L1_CACHE + KM_TYPE_NR * cpu; | ||
192 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
193 | ptep = TOP_PTE(vaddr); | ||
194 | pte = mk_pte(page, kmap_prot); | ||
195 | |||
196 | BUG_ON(pte_val(*ptep) != pte_val(pte)); | ||
197 | BUG_ON(*depth <= 0); | ||
198 | |||
199 | raw_local_irq_save(flags); | ||
200 | (*depth)--; | ||
201 | if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) { | ||
202 | set_pte_ext(ptep, saved_pte, 0); | ||
203 | local_flush_tlb_kernel_page(vaddr); | ||
204 | } | ||
205 | raw_local_irq_restore(flags); | ||
206 | |||
207 | if (!in_interrupt()) | ||
208 | preempt_enable(); | ||
209 | } | ||
210 | |||
211 | #endif /* CONFIG_CPU_CACHE_VIPT */ | ||
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d4da6ac28eb..241c24a1c18f 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -420,6 +420,10 @@ static void __init build_mem_type_table(void) | |||
420 | user_pgprot |= L_PTE_SHARED; | 420 | user_pgprot |= L_PTE_SHARED; |
421 | kern_pgprot |= L_PTE_SHARED; | 421 | kern_pgprot |= L_PTE_SHARED; |
422 | vecs_pgprot |= L_PTE_SHARED; | 422 | vecs_pgprot |= L_PTE_SHARED; |
423 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; | ||
424 | mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; | ||
425 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; | ||
426 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | ||
423 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 427 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
424 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | 428 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; |
425 | #endif | 429 | #endif |
@@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode) | |||
1050 | pgd_t *pgd; | 1054 | pgd_t *pgd; |
1051 | int i; | 1055 | int i; |
1052 | 1056 | ||
1053 | if (current->mm && current->mm->pgd) | 1057 | /* |
1054 | pgd = current->mm->pgd; | 1058 | * We need to access to user-mode page tables here. For kernel threads |
1055 | else | 1059 | * we don't have any user-mode mappings so we use the context that we |
1056 | pgd = init_mm.pgd; | 1060 | * "borrowed". |
1061 | */ | ||
1062 | pgd = current->active_mm->pgd; | ||
1057 | 1063 | ||
1058 | base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; | 1064 | base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; |
1059 | if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) | 1065 | if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h index 2bbd6ed17f50..da92933a233b 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h | |||
@@ -8,8 +8,8 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ |
12 | #define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ |
13 | 13 | ||
14 | /* Definitions for components on the Debug board */ | 14 | /* Definitions for components on the Debug board */ |
15 | 15 | ||
@@ -56,4 +56,4 @@ | |||
56 | 56 | ||
57 | #define MXC_MAX_EXP_IO_LINES 16 | 57 | #define MXC_MAX_EXP_IO_LINES 16 |
58 | 58 | ||
59 | #endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */ | 59 | #endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 771532b6b4a6..5aad344d5651 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h | |||
@@ -14,7 +14,7 @@ | |||
14 | * FB100000 70000000 1M SPBA 0 | 14 | * FB100000 70000000 1M SPBA 0 |
15 | * FB000000 73F00000 1M AIPS 1 | 15 | * FB000000 73F00000 1M AIPS 1 |
16 | * FB200000 83F00000 1M AIPS 2 | 16 | * FB200000 83F00000 1M AIPS 2 |
17 | * FA100000 8FFFC000 16K TZIC (interrupt controller) | 17 | * 8FFFC000 16K TZIC (interrupt controller) |
18 | * 90000000 256M CSD0 SDRAM/DDR | 18 | * 90000000 256M CSD0 SDRAM/DDR |
19 | * A0000000 256M CSD1 SDRAM/DDR | 19 | * A0000000 256M CSD1 SDRAM/DDR |
20 | * B0000000 128M CS0 Flash | 20 | * B0000000 128M CS0 Flash |
@@ -23,11 +23,17 @@ | |||
23 | * C8000000 64M CS3 Flash | 23 | * C8000000 64M CS3 Flash |
24 | * CC000000 32M CS4 SRAM | 24 | * CC000000 32M CS4 SRAM |
25 | * CE000000 32M CS5 SRAM | 25 | * CE000000 32M CS5 SRAM |
26 | * F9000000 CFFF0000 64K NFC (NAND Flash AXI) | 26 | * CFFF0000 64K NFC (NAND Flash AXI) |
27 | * | 27 | * |
28 | */ | 28 | */ |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * IROM | ||
32 | */ | ||
33 | #define MX51_IROM_BASE_ADDR 0x0 | ||
34 | #define MX51_IROM_SIZE SZ_64K | ||
35 | |||
36 | /* | ||
31 | * IRAM | 37 | * IRAM |
32 | */ | 38 | */ |
33 | #define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ | 39 | #define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ |
@@ -40,7 +46,6 @@ | |||
40 | * NFC | 46 | * NFC |
41 | */ | 47 | */ |
42 | #define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */ | 48 | #define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */ |
43 | #define MX51_NFC_AXI_BASE_ADDR_VIRT 0xF9000000 | ||
44 | #define MX51_NFC_AXI_SIZE SZ_64K | 49 | #define MX51_NFC_AXI_SIZE SZ_64K |
45 | 50 | ||
46 | /* | 51 | /* |
@@ -49,9 +54,8 @@ | |||
49 | #define MX51_GPU_BASE_ADDR 0x20000000 | 54 | #define MX51_GPU_BASE_ADDR 0x20000000 |
50 | #define MX51_GPU2D_BASE_ADDR 0xD0000000 | 55 | #define MX51_GPU2D_BASE_ADDR 0xD0000000 |
51 | 56 | ||
52 | #define MX51_TZIC_BASE_ADDR 0x8FFFC000 | 57 | #define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000 |
53 | #define MX51_TZIC_BASE_ADDR_VIRT 0xFA100000 | 58 | #define MX51_TZIC_BASE_ADDR 0xE0000000 |
54 | #define MX51_TZIC_SIZE SZ_16K | ||
55 | 59 | ||
56 | #define MX51_DEBUG_BASE_ADDR 0x60000000 | 60 | #define MX51_DEBUG_BASE_ADDR 0x60000000 |
57 | #define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000 | 61 | #define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000 |
@@ -232,12 +236,10 @@ | |||
232 | #define MX51_IO_ADDRESS(x) \ | 236 | #define MX51_IO_ADDRESS(x) \ |
233 | (void __iomem *) \ | 237 | (void __iomem *) \ |
234 | (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \ | 238 | (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \ |
235 | MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) : \ | ||
236 | MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ | 239 | MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ |
237 | MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ | 240 | MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ |
238 | MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ | 241 | MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ |
239 | MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ | 242 | MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ |
240 | MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \ | ||
241 | 0xDEADBEEF) | 243 | 0xDEADBEEF) |
242 | 244 | ||
243 | /* | 245 | /* |
@@ -246,9 +248,6 @@ | |||
246 | #define MX51_IRAM_IO_ADDRESS(x) \ | 248 | #define MX51_IRAM_IO_ADDRESS(x) \ |
247 | (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT) | 249 | (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT) |
248 | 250 | ||
249 | #define MX51_TZIC_IO_ADDRESS(x) \ | ||
250 | (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT) | ||
251 | |||
252 | #define MX51_DEBUG_IO_ADDRESS(x) \ | 251 | #define MX51_DEBUG_IO_ADDRESS(x) \ |
253 | (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT) | 252 | (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT) |
254 | 253 | ||
@@ -261,9 +260,6 @@ | |||
261 | #define MX51_AIPS2_IO_ADDRESS(x) \ | 260 | #define MX51_AIPS2_IO_ADDRESS(x) \ |
262 | (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT) | 261 | (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT) |
263 | 262 | ||
264 | #define MX51_NFC_AXI_IO_ADDRESS(x) \ | ||
265 | (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT) | ||
266 | |||
267 | #define MX51_IS_MEM_DEVICE_NONSHARED(x) 0 | 263 | #define MX51_IS_MEM_DEVICE_NONSHARED(x) 0 |
268 | 264 | ||
269 | /* | 265 | /* |
@@ -443,12 +439,7 @@ | |||
443 | 439 | ||
444 | #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) | 440 | #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) |
445 | 441 | ||
446 | extern unsigned int system_rev; | 442 | extern int mx51_revision(void); |
447 | |||
448 | static inline unsigned int mx51_revision(void) | ||
449 | { | ||
450 | return system_rev; | ||
451 | } | ||
452 | #endif | 443 | #endif |
453 | 444 | ||
454 | #endif /* __ASM_ARCH_MXC_MX51_H__ */ | 445 | #endif /* __ASM_ARCH_MXC_MX51_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index 52e476a150ca..b6d3d0fddc48 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h | |||
@@ -66,6 +66,7 @@ static inline void flush(void) | |||
66 | #define MX2X_UART1_BASE_ADDR 0x1000a000 | 66 | #define MX2X_UART1_BASE_ADDR 0x1000a000 |
67 | #define MX3X_UART1_BASE_ADDR 0x43F90000 | 67 | #define MX3X_UART1_BASE_ADDR 0x43F90000 |
68 | #define MX3X_UART2_BASE_ADDR 0x43F94000 | 68 | #define MX3X_UART2_BASE_ADDR 0x43F94000 |
69 | #define MX51_UART1_BASE_ADDR 0x73fbc000 | ||
69 | 70 | ||
70 | static __inline__ void __arch_decomp_setup(unsigned long arch_id) | 71 | static __inline__ void __arch_decomp_setup(unsigned long arch_id) |
71 | { | 72 | { |
@@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) | |||
101 | case MACH_TYPE_MAGX_ZN5: | 102 | case MACH_TYPE_MAGX_ZN5: |
102 | uart_base = MX3X_UART2_BASE_ADDR; | 103 | uart_base = MX3X_UART2_BASE_ADDR; |
103 | break; | 104 | break; |
105 | case MACH_TYPE_MX51_BABBAGE: | ||
106 | uart_base = MX51_UART1_BASE_ADDR; | ||
107 | break; | ||
104 | default: | 108 | default: |
105 | break; | 109 | break; |
106 | } | 110 | } |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index a420cb949328..315a540c7ce5 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -428,26 +428,6 @@ static void vfp_pm_init(void) | |||
428 | static inline void vfp_pm_init(void) { } | 428 | static inline void vfp_pm_init(void) { } |
429 | #endif /* CONFIG_PM */ | 429 | #endif /* CONFIG_PM */ |
430 | 430 | ||
431 | /* | ||
432 | * Synchronise the hardware VFP state of a thread other than current with the | ||
433 | * saved one. This function is used by the ptrace mechanism. | ||
434 | */ | ||
435 | #ifdef CONFIG_SMP | ||
436 | void vfp_sync_hwstate(struct thread_info *thread) | ||
437 | { | ||
438 | } | ||
439 | |||
440 | void vfp_flush_hwstate(struct thread_info *thread) | ||
441 | { | ||
442 | /* | ||
443 | * On SMP systems, the VFP state is automatically saved at every | ||
444 | * context switch. We mark the thread VFP state as belonging to a | ||
445 | * non-existent CPU so that the saved one will be reloaded when | ||
446 | * needed. | ||
447 | */ | ||
448 | thread->vfpstate.hard.cpu = NR_CPUS; | ||
449 | } | ||
450 | #else | ||
451 | void vfp_sync_hwstate(struct thread_info *thread) | 431 | void vfp_sync_hwstate(struct thread_info *thread) |
452 | { | 432 | { |
453 | unsigned int cpu = get_cpu(); | 433 | unsigned int cpu = get_cpu(); |
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread) | |||
490 | last_VFP_context[cpu] = NULL; | 470 | last_VFP_context[cpu] = NULL; |
491 | } | 471 | } |
492 | 472 | ||
473 | #ifdef CONFIG_SMP | ||
474 | /* | ||
475 | * For SMP we still have to take care of the case where the thread | ||
476 | * migrates to another CPU and then back to the original CPU on which | ||
477 | * the last VFP user is still the same thread. Mark the thread VFP | ||
478 | * state as belonging to a non-existent CPU so that the saved one will | ||
479 | * be reloaded in the above case. | ||
480 | */ | ||
481 | thread->vfpstate.hard.cpu = NR_CPUS; | ||
482 | #endif | ||
493 | put_cpu(); | 483 | put_cpu(); |
494 | } | 484 | } |
495 | #endif | ||
496 | 485 | ||
497 | #include <linux/smp.h> | 486 | #include <linux/smp.h> |
498 | 487 | ||
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 73c5c2b05f64..d7bac1f75af0 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -979,11 +979,13 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
979 | r = -EFAULT; | 979 | r = -EFAULT; |
980 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | 980 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) |
981 | goto out; | 981 | goto out; |
982 | r = -ENXIO; | ||
982 | if (irqchip_in_kernel(kvm)) { | 983 | if (irqchip_in_kernel(kvm)) { |
983 | __s32 status; | 984 | __s32 status; |
984 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 985 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
985 | irq_event.irq, irq_event.level); | 986 | irq_event.irq, irq_event.level); |
986 | if (ioctl == KVM_IRQ_LINE_STATUS) { | 987 | if (ioctl == KVM_IRQ_LINE_STATUS) { |
988 | r = -EFAULT; | ||
987 | irq_event.status = status; | 989 | irq_event.status = status; |
988 | if (copy_to_user(argp, &irq_event, | 990 | if (copy_to_user(argp, &irq_event, |
989 | sizeof irq_event)) | 991 | sizeof irq_event)) |
@@ -1535,8 +1537,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
1535 | goto out; | 1537 | goto out; |
1536 | 1538 | ||
1537 | if (copy_to_user(user_stack, stack, | 1539 | if (copy_to_user(user_stack, stack, |
1538 | sizeof(struct kvm_ia64_vcpu_stack))) | 1540 | sizeof(struct kvm_ia64_vcpu_stack))) { |
1541 | r = -EFAULT; | ||
1539 | goto out; | 1542 | goto out; |
1543 | } | ||
1540 | 1544 | ||
1541 | break; | 1545 | break; |
1542 | } | 1546 | } |
@@ -1802,7 +1806,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm, | |||
1802 | { | 1806 | { |
1803 | struct kvm_memory_slot *memslot; | 1807 | struct kvm_memory_slot *memslot; |
1804 | int r, i; | 1808 | int r, i; |
1805 | long n, base; | 1809 | long base; |
1810 | unsigned long n; | ||
1806 | unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base + | 1811 | unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base + |
1807 | offsetof(struct kvm_vm_data, kvm_mem_dirty_log)); | 1812 | offsetof(struct kvm_vm_data, kvm_mem_dirty_log)); |
1808 | 1813 | ||
@@ -1815,7 +1820,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm, | |||
1815 | if (!memslot->dirty_bitmap) | 1820 | if (!memslot->dirty_bitmap) |
1816 | goto out; | 1821 | goto out; |
1817 | 1822 | ||
1818 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 1823 | n = kvm_dirty_bitmap_bytes(memslot); |
1819 | base = memslot->base_gfn / BITS_PER_LONG; | 1824 | base = memslot->base_gfn / BITS_PER_LONG; |
1820 | 1825 | ||
1821 | for (i = 0; i < n/sizeof(long); ++i) { | 1826 | for (i = 0; i < n/sizeof(long); ++i) { |
@@ -1831,7 +1836,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
1831 | struct kvm_dirty_log *log) | 1836 | struct kvm_dirty_log *log) |
1832 | { | 1837 | { |
1833 | int r; | 1838 | int r; |
1834 | int n; | 1839 | unsigned long n; |
1835 | struct kvm_memory_slot *memslot; | 1840 | struct kvm_memory_slot *memslot; |
1836 | int is_dirty = 0; | 1841 | int is_dirty = 0; |
1837 | 1842 | ||
@@ -1850,7 +1855,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
1850 | if (is_dirty) { | 1855 | if (is_dirty) { |
1851 | kvm_flush_remote_tlbs(kvm); | 1856 | kvm_flush_remote_tlbs(kvm); |
1852 | memslot = &kvm->memslots->memslots[log->slot]; | 1857 | memslot = &kvm->memslots->memslots[log->slot]; |
1853 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 1858 | n = kvm_dirty_bitmap_bytes(memslot); |
1854 | memset(memslot->dirty_bitmap, 0, n); | 1859 | memset(memslot->dirty_bitmap, 0, n); |
1855 | } | 1860 | } |
1856 | r = 0; | 1861 | r = 0; |
diff --git a/arch/m68k/include/asm/atomic_mm.h b/arch/m68k/include/asm/atomic_mm.h index 88b7af20a996..d9d2ed647435 100644 --- a/arch/m68k/include/asm/atomic_mm.h +++ b/arch/m68k/include/asm/atomic_mm.h | |||
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new) | |||
148 | static inline int atomic_sub_and_test(int i, atomic_t *v) | 148 | static inline int atomic_sub_and_test(int i, atomic_t *v) |
149 | { | 149 | { |
150 | char c; | 150 | char c; |
151 | __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i)); | 151 | __asm__ __volatile__("subl %2,%1; seq %0" |
152 | : "=d" (c), "+m" (*v) | ||
153 | : "id" (i)); | ||
152 | return c != 0; | 154 | return c != 0; |
153 | } | 155 | } |
154 | 156 | ||
155 | static inline int atomic_add_negative(int i, atomic_t *v) | 157 | static inline int atomic_add_negative(int i, atomic_t *v) |
156 | { | 158 | { |
157 | char c; | 159 | char c; |
158 | __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i)); | 160 | __asm__ __volatile__("addl %2,%1; smi %0" |
161 | : "=d" (c), "+m" (*v) | ||
162 | : "id" (i)); | ||
159 | return c != 0; | 163 | return c != 0; |
160 | } | 164 | } |
161 | 165 | ||
diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h index ef2293873612..01a8716c5fc5 100644 --- a/arch/m68k/include/asm/mcfuart.h +++ b/arch/m68k/include/asm/mcfuart.h | |||
@@ -212,5 +212,10 @@ struct mcf_platform_uart { | |||
212 | #define MCFUART_URF_RXS 0xc0 /* Receiver status */ | 212 | #define MCFUART_URF_RXS 0xc0 /* Receiver status */ |
213 | #endif | 213 | #endif |
214 | 214 | ||
215 | #if defined(CONFIG_M5272) | ||
216 | #define MCFUART_TXFIFOSIZE 25 | ||
217 | #else | ||
218 | #define MCFUART_TXFIFOSIZE 1 | ||
219 | #endif | ||
215 | /****************************************************************************/ | 220 | /****************************************************************************/ |
216 | #endif /* mcfuart_h */ | 221 | #endif /* mcfuart_h */ |
diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h index 1320eaa4cc2a..a29dd74a17cb 100644 --- a/arch/m68k/include/asm/sigcontext.h +++ b/arch/m68k/include/asm/sigcontext.h | |||
@@ -17,13 +17,11 @@ struct sigcontext { | |||
17 | #ifndef __uClinux__ | 17 | #ifndef __uClinux__ |
18 | # ifdef __mcoldfire__ | 18 | # ifdef __mcoldfire__ |
19 | unsigned long sc_fpregs[2][2]; /* room for two fp registers */ | 19 | unsigned long sc_fpregs[2][2]; /* room for two fp registers */ |
20 | unsigned long sc_fpcntl[3]; | ||
21 | unsigned char sc_fpstate[16+6*8]; | ||
22 | # else | 20 | # else |
23 | unsigned long sc_fpregs[2*3]; /* room for two fp registers */ | 21 | unsigned long sc_fpregs[2*3]; /* room for two fp registers */ |
22 | # endif | ||
24 | unsigned long sc_fpcntl[3]; | 23 | unsigned long sc_fpcntl[3]; |
25 | unsigned char sc_fpstate[216]; | 24 | unsigned char sc_fpstate[216]; |
26 | # endif | ||
27 | #endif | 25 | #endif |
28 | }; | 26 | }; |
29 | 27 | ||
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile index ce404bc9ccbd..14042574ac21 100644 --- a/arch/m68knommu/Makefile +++ b/arch/m68knommu/Makefile | |||
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200) | |||
94 | cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307) | 94 | cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307) |
95 | cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200) | 95 | cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200) |
96 | cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307) | 96 | cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307) |
97 | cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200) | 97 | cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307) |
98 | cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307) | 98 | cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307) |
99 | cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307) | 99 | cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307) |
100 | cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200) | 100 | cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200) |
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S index 56043ade3941..aff6f57ef8b5 100644 --- a/arch/m68knommu/kernel/entry.S +++ b/arch/m68knommu/kernel/entry.S | |||
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal) | |||
145 | trap #0 | 145 | trap #0 |
146 | 146 | ||
147 | ENTRY(ret_from_user_rt_signal) | 147 | ENTRY(ret_from_user_rt_signal) |
148 | move #__NR_rt_sigreturn,%d0 | 148 | movel #__NR_rt_sigreturn,%d0 |
149 | trap #0 | 149 | trap #0 |
150 | 150 | ||
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index 1143f77caca4..6f22970d8c20 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c | |||
@@ -107,7 +107,6 @@ void init_IRQ(void) | |||
107 | _ramvec[vba+CPMVEC_PIO_PC7] = inthandler; /* pio - pc7 */ | 107 | _ramvec[vba+CPMVEC_PIO_PC7] = inthandler; /* pio - pc7 */ |
108 | _ramvec[vba+CPMVEC_PIO_PC6] = inthandler; /* pio - pc6 */ | 108 | _ramvec[vba+CPMVEC_PIO_PC6] = inthandler; /* pio - pc6 */ |
109 | _ramvec[vba+CPMVEC_TIMER3] = inthandler; /* timer 3 */ | 109 | _ramvec[vba+CPMVEC_TIMER3] = inthandler; /* timer 3 */ |
110 | _ramvec[vba+CPMVEC_RISCTIMER] = inthandler; /* reserved */ | ||
111 | _ramvec[vba+CPMVEC_PIO_PC5] = inthandler; /* pio - pc5 */ | 110 | _ramvec[vba+CPMVEC_PIO_PC5] = inthandler; /* pio - pc5 */ |
112 | _ramvec[vba+CPMVEC_PIO_PC4] = inthandler; /* pio - pc4 */ | 111 | _ramvec[vba+CPMVEC_PIO_PC4] = inthandler; /* pio - pc4 */ |
113 | _ramvec[vba+CPMVEC_RESERVED2] = inthandler; /* reserved */ | 112 | _ramvec[vba+CPMVEC_RESERVED2] = inthandler; /* reserved */ |
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c index 379536e3abd1..be7e92ea01f3 100644 --- a/arch/mips/alchemy/devboards/db1200/setup.c +++ b/arch/mips/alchemy/devboards/db1200/setup.c | |||
@@ -60,43 +60,6 @@ void __init board_setup(void) | |||
60 | wmb(); | 60 | wmb(); |
61 | } | 61 | } |
62 | 62 | ||
63 | /* use the hexleds to count the number of times the cpu has entered | ||
64 | * wait, the dots to indicate whether the CPU is currently idle or | ||
65 | * active (dots off = sleeping, dots on = working) for cases where | ||
66 | * the number doesn't change for a long(er) period of time. | ||
67 | */ | ||
68 | static void db1200_wait(void) | ||
69 | { | ||
70 | __asm__(" .set push \n" | ||
71 | " .set mips3 \n" | ||
72 | " .set noreorder \n" | ||
73 | " cache 0x14, 0(%0) \n" | ||
74 | " cache 0x14, 32(%0) \n" | ||
75 | " cache 0x14, 64(%0) \n" | ||
76 | /* dots off: we're about to call wait */ | ||
77 | " lui $26, 0xb980 \n" | ||
78 | " ori $27, $0, 3 \n" | ||
79 | " sb $27, 0x18($26) \n" | ||
80 | " sync \n" | ||
81 | " nop \n" | ||
82 | " wait \n" | ||
83 | " nop \n" | ||
84 | " nop \n" | ||
85 | " nop \n" | ||
86 | " nop \n" | ||
87 | " nop \n" | ||
88 | /* dots on: there's work to do, increment cntr */ | ||
89 | " lui $26, 0xb980 \n" | ||
90 | " sb $0, 0x18($26) \n" | ||
91 | " lui $26, 0xb9c0 \n" | ||
92 | " lb $27, 0($26) \n" | ||
93 | " addiu $27, $27, 1 \n" | ||
94 | " sb $27, 0($26) \n" | ||
95 | " sync \n" | ||
96 | " .set pop \n" | ||
97 | : : "r" (db1200_wait)); | ||
98 | } | ||
99 | |||
100 | static int __init db1200_arch_init(void) | 63 | static int __init db1200_arch_init(void) |
101 | { | 64 | { |
102 | /* GPIO7 is low-level triggered CPLD cascade */ | 65 | /* GPIO7 is low-level triggered CPLD cascade */ |
@@ -110,9 +73,6 @@ static int __init db1200_arch_init(void) | |||
110 | irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; | 73 | irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN; |
111 | irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; | 74 | irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN; |
112 | 75 | ||
113 | if (cpu_wait) | ||
114 | cpu_wait = db1200_wait; | ||
115 | |||
116 | return 0; | 76 | return 0; |
117 | } | 77 | } |
118 | arch_initcall(db1200_arch_init); | 78 | arch_initcall(db1200_arch_init); |
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 246df7aca2e7..2fafc78e5ce1 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c | |||
@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = { | |||
168 | .on = vlynq_on, | 168 | .on = vlynq_on, |
169 | .off = vlynq_off, | 169 | .off = vlynq_off, |
170 | }, | 170 | }, |
171 | .reset_bit = 26, | 171 | .reset_bit = 16, |
172 | .gpio_bit = 19, | 172 | .gpio_bit = 19, |
173 | }; | 173 | }; |
174 | 174 | ||
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void) | |||
600 | } | 600 | } |
601 | 601 | ||
602 | if (ar7_has_high_cpmac()) { | 602 | if (ar7_has_high_cpmac()) { |
603 | res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); | ||
603 | if (!res) { | 604 | if (!res) { |
604 | cpmac_get_mac(1, cpmac_high_data.dev_addr); | 605 | cpmac_get_mac(1, cpmac_high_data.dev_addr); |
605 | 606 | ||
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index ea17941168ca..8dba8cfb752f 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/addrspace.h> | 18 | #include <asm/addrspace.h> |
19 | #include <bcm63xx_board.h> | 19 | #include <bcm63xx_board.h> |
20 | #include <bcm63xx_cpu.h> | 20 | #include <bcm63xx_cpu.h> |
21 | #include <bcm63xx_dev_uart.h> | ||
21 | #include <bcm63xx_regs.h> | 22 | #include <bcm63xx_regs.h> |
22 | #include <bcm63xx_io.h> | 23 | #include <bcm63xx_io.h> |
23 | #include <bcm63xx_dev_pci.h> | 24 | #include <bcm63xx_dev_pci.h> |
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = { | |||
40 | .name = "96338GW", | 41 | .name = "96338GW", |
41 | .expected_cpu_id = 0x6338, | 42 | .expected_cpu_id = 0x6338, |
42 | 43 | ||
44 | .has_uart0 = 1, | ||
43 | .has_enet0 = 1, | 45 | .has_enet0 = 1, |
44 | .enet0 = { | 46 | .enet0 = { |
45 | .force_speed_100 = 1, | 47 | .force_speed_100 = 1, |
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = { | |||
82 | .name = "96338W", | 84 | .name = "96338W", |
83 | .expected_cpu_id = 0x6338, | 85 | .expected_cpu_id = 0x6338, |
84 | 86 | ||
87 | .has_uart0 = 1, | ||
85 | .has_enet0 = 1, | 88 | .has_enet0 = 1, |
86 | .enet0 = { | 89 | .enet0 = { |
87 | .force_speed_100 = 1, | 90 | .force_speed_100 = 1, |
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = { | |||
126 | static struct board_info __initdata board_96345gw2 = { | 129 | static struct board_info __initdata board_96345gw2 = { |
127 | .name = "96345GW2", | 130 | .name = "96345GW2", |
128 | .expected_cpu_id = 0x6345, | 131 | .expected_cpu_id = 0x6345, |
132 | |||
133 | .has_uart0 = 1, | ||
129 | }; | 134 | }; |
130 | #endif | 135 | #endif |
131 | 136 | ||
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = { | |||
137 | .name = "96348R", | 142 | .name = "96348R", |
138 | .expected_cpu_id = 0x6348, | 143 | .expected_cpu_id = 0x6348, |
139 | 144 | ||
145 | .has_uart0 = 1, | ||
140 | .has_enet0 = 1, | 146 | .has_enet0 = 1, |
141 | .has_pci = 1, | 147 | .has_pci = 1, |
142 | 148 | ||
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = { | |||
180 | .name = "96348GW-10", | 186 | .name = "96348GW-10", |
181 | .expected_cpu_id = 0x6348, | 187 | .expected_cpu_id = 0x6348, |
182 | 188 | ||
189 | .has_uart0 = 1, | ||
183 | .has_enet0 = 1, | 190 | .has_enet0 = 1, |
184 | .has_enet1 = 1, | 191 | .has_enet1 = 1, |
185 | .has_pci = 1, | 192 | .has_pci = 1, |
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = { | |||
239 | .name = "96348GW-11", | 246 | .name = "96348GW-11", |
240 | .expected_cpu_id = 0x6348, | 247 | .expected_cpu_id = 0x6348, |
241 | 248 | ||
249 | .has_uart0 = 1, | ||
242 | .has_enet0 = 1, | 250 | .has_enet0 = 1, |
243 | .has_enet1 = 1, | 251 | .has_enet1 = 1, |
244 | .has_pci = 1, | 252 | .has_pci = 1, |
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = { | |||
292 | .name = "96348GW", | 300 | .name = "96348GW", |
293 | .expected_cpu_id = 0x6348, | 301 | .expected_cpu_id = 0x6348, |
294 | 302 | ||
303 | .has_uart0 = 1, | ||
295 | .has_enet0 = 1, | 304 | .has_enet0 = 1, |
296 | .has_enet1 = 1, | 305 | .has_enet1 = 1, |
297 | .has_pci = 1, | 306 | .has_pci = 1, |
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = { | |||
349 | .name = "F@ST2404", | 358 | .name = "F@ST2404", |
350 | .expected_cpu_id = 0x6348, | 359 | .expected_cpu_id = 0x6348, |
351 | 360 | ||
352 | .has_enet0 = 1, | 361 | .has_uart0 = 1, |
353 | .has_enet1 = 1, | 362 | .has_enet0 = 1, |
354 | .has_pci = 1, | 363 | .has_enet1 = 1, |
364 | .has_pci = 1, | ||
355 | 365 | ||
356 | .enet0 = { | 366 | .enet0 = { |
357 | .has_phy = 1, | 367 | .has_phy = 1, |
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = { | |||
368 | .has_ehci0 = 1, | 378 | .has_ehci0 = 1, |
369 | }; | 379 | }; |
370 | 380 | ||
381 | static struct board_info __initdata board_rta1025w_16 = { | ||
382 | .name = "RTA1025W_16", | ||
383 | .expected_cpu_id = 0x6348, | ||
384 | |||
385 | .has_enet0 = 1, | ||
386 | .has_enet1 = 1, | ||
387 | .has_pci = 1, | ||
388 | |||
389 | .enet0 = { | ||
390 | .has_phy = 1, | ||
391 | .use_internal_phy = 1, | ||
392 | }, | ||
393 | .enet1 = { | ||
394 | .force_speed_100 = 1, | ||
395 | .force_duplex_full = 1, | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | |||
371 | static struct board_info __initdata board_DV201AMR = { | 400 | static struct board_info __initdata board_DV201AMR = { |
372 | .name = "DV201AMR", | 401 | .name = "DV201AMR", |
373 | .expected_cpu_id = 0x6348, | 402 | .expected_cpu_id = 0x6348, |
374 | 403 | ||
404 | .has_uart0 = 1, | ||
375 | .has_pci = 1, | 405 | .has_pci = 1, |
376 | .has_ohci0 = 1, | 406 | .has_ohci0 = 1, |
377 | 407 | ||
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = { | |||
391 | .name = "96348GW-A", | 421 | .name = "96348GW-A", |
392 | .expected_cpu_id = 0x6348, | 422 | .expected_cpu_id = 0x6348, |
393 | 423 | ||
424 | .has_uart0 = 1, | ||
394 | .has_enet0 = 1, | 425 | .has_enet0 = 1, |
395 | .has_enet1 = 1, | 426 | .has_enet1 = 1, |
396 | .has_pci = 1, | 427 | .has_pci = 1, |
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = { | |||
416 | .name = "96358VW", | 447 | .name = "96358VW", |
417 | .expected_cpu_id = 0x6358, | 448 | .expected_cpu_id = 0x6358, |
418 | 449 | ||
450 | .has_uart0 = 1, | ||
419 | .has_enet0 = 1, | 451 | .has_enet0 = 1, |
420 | .has_enet1 = 1, | 452 | .has_enet1 = 1, |
421 | .has_pci = 1, | 453 | .has_pci = 1, |
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = { | |||
467 | .name = "96358VW2", | 499 | .name = "96358VW2", |
468 | .expected_cpu_id = 0x6358, | 500 | .expected_cpu_id = 0x6358, |
469 | 501 | ||
502 | .has_uart0 = 1, | ||
470 | .has_enet0 = 1, | 503 | .has_enet0 = 1, |
471 | .has_enet1 = 1, | 504 | .has_enet1 = 1, |
472 | .has_pci = 1, | 505 | .has_pci = 1, |
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = { | |||
514 | .name = "AGPF-S0", | 547 | .name = "AGPF-S0", |
515 | .expected_cpu_id = 0x6358, | 548 | .expected_cpu_id = 0x6358, |
516 | 549 | ||
550 | .has_uart0 = 1, | ||
517 | .has_enet0 = 1, | 551 | .has_enet0 = 1, |
518 | .has_enet1 = 1, | 552 | .has_enet1 = 1, |
519 | .has_pci = 1, | 553 | .has_pci = 1, |
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = { | |||
531 | .has_ohci0 = 1, | 565 | .has_ohci0 = 1, |
532 | .has_ehci0 = 1, | 566 | .has_ehci0 = 1, |
533 | }; | 567 | }; |
568 | |||
569 | static struct board_info __initdata board_DWVS0 = { | ||
570 | .name = "DWV-S0", | ||
571 | .expected_cpu_id = 0x6358, | ||
572 | |||
573 | .has_enet0 = 1, | ||
574 | .has_enet1 = 1, | ||
575 | .has_pci = 1, | ||
576 | |||
577 | .enet0 = { | ||
578 | .has_phy = 1, | ||
579 | .use_internal_phy = 1, | ||
580 | }, | ||
581 | |||
582 | .enet1 = { | ||
583 | .force_speed_100 = 1, | ||
584 | .force_duplex_full = 1, | ||
585 | }, | ||
586 | |||
587 | .has_ohci0 = 1, | ||
588 | }; | ||
534 | #endif | 589 | #endif |
535 | 590 | ||
536 | /* | 591 | /* |
@@ -552,16 +607,88 @@ static const struct board_info __initdata *bcm963xx_boards[] = { | |||
552 | &board_FAST2404, | 607 | &board_FAST2404, |
553 | &board_DV201AMR, | 608 | &board_DV201AMR, |
554 | &board_96348gw_a, | 609 | &board_96348gw_a, |
610 | &board_rta1025w_16, | ||
555 | #endif | 611 | #endif |
556 | 612 | ||
557 | #ifdef CONFIG_BCM63XX_CPU_6358 | 613 | #ifdef CONFIG_BCM63XX_CPU_6358 |
558 | &board_96358vw, | 614 | &board_96358vw, |
559 | &board_96358vw2, | 615 | &board_96358vw2, |
560 | &board_AGPFS0, | 616 | &board_AGPFS0, |
617 | &board_DWVS0, | ||
561 | #endif | 618 | #endif |
562 | }; | 619 | }; |
563 | 620 | ||
564 | /* | 621 | /* |
622 | * Register a sane SPROMv2 to make the on-board | ||
623 | * bcm4318 WLAN work | ||
624 | */ | ||
625 | #ifdef CONFIG_SSB_PCIHOST | ||
626 | static struct ssb_sprom bcm63xx_sprom = { | ||
627 | .revision = 0x02, | ||
628 | .board_rev = 0x17, | ||
629 | .country_code = 0x0, | ||
630 | .ant_available_bg = 0x3, | ||
631 | .pa0b0 = 0x15ae, | ||
632 | .pa0b1 = 0xfa85, | ||
633 | .pa0b2 = 0xfe8d, | ||
634 | .pa1b0 = 0xffff, | ||
635 | .pa1b1 = 0xffff, | ||
636 | .pa1b2 = 0xffff, | ||
637 | .gpio0 = 0xff, | ||
638 | .gpio1 = 0xff, | ||
639 | .gpio2 = 0xff, | ||
640 | .gpio3 = 0xff, | ||
641 | .maxpwr_bg = 0x004c, | ||
642 | .itssi_bg = 0x00, | ||
643 | .boardflags_lo = 0x2848, | ||
644 | .boardflags_hi = 0x0000, | ||
645 | }; | ||
646 | #endif | ||
647 | |||
648 | /* | ||
649 | * return board name for /proc/cpuinfo | ||
650 | */ | ||
651 | const char *board_get_name(void) | ||
652 | { | ||
653 | return board.name; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * register & return a new board mac address | ||
658 | */ | ||
659 | static int board_get_mac_address(u8 *mac) | ||
660 | { | ||
661 | u8 *p; | ||
662 | int count; | ||
663 | |||
664 | if (mac_addr_used >= nvram.mac_addr_count) { | ||
665 | printk(KERN_ERR PFX "not enough mac address\n"); | ||
666 | return -ENODEV; | ||
667 | } | ||
668 | |||
669 | memcpy(mac, nvram.mac_addr_base, ETH_ALEN); | ||
670 | p = mac + ETH_ALEN - 1; | ||
671 | count = mac_addr_used; | ||
672 | |||
673 | while (count--) { | ||
674 | do { | ||
675 | (*p)++; | ||
676 | if (*p != 0) | ||
677 | break; | ||
678 | p--; | ||
679 | } while (p != mac); | ||
680 | } | ||
681 | |||
682 | if (p == mac) { | ||
683 | printk(KERN_ERR PFX "unable to fetch mac address\n"); | ||
684 | return -ENODEV; | ||
685 | } | ||
686 | |||
687 | mac_addr_used++; | ||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | /* | ||
565 | * early init callback, read nvram data from flash and checksum it | 692 | * early init callback, read nvram data from flash and checksum it |
566 | */ | 693 | */ |
567 | void __init board_prom_init(void) | 694 | void __init board_prom_init(void) |
@@ -659,6 +786,17 @@ void __init board_prom_init(void) | |||
659 | } | 786 | } |
660 | 787 | ||
661 | bcm_gpio_writel(val, GPIO_MODE_REG); | 788 | bcm_gpio_writel(val, GPIO_MODE_REG); |
789 | |||
790 | /* Generate MAC address for WLAN and | ||
791 | * register our SPROM */ | ||
792 | #ifdef CONFIG_SSB_PCIHOST | ||
793 | if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { | ||
794 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); | ||
795 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); | ||
796 | if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) | ||
797 | printk(KERN_ERR "failed to register fallback SPROM\n"); | ||
798 | } | ||
799 | #endif | ||
662 | } | 800 | } |
663 | 801 | ||
664 | /* | 802 | /* |
@@ -676,49 +814,6 @@ void __init board_setup(void) | |||
676 | panic("unexpected CPU for bcm963xx board"); | 814 | panic("unexpected CPU for bcm963xx board"); |
677 | } | 815 | } |
678 | 816 | ||
679 | /* | ||
680 | * return board name for /proc/cpuinfo | ||
681 | */ | ||
682 | const char *board_get_name(void) | ||
683 | { | ||
684 | return board.name; | ||
685 | } | ||
686 | |||
687 | /* | ||
688 | * register & return a new board mac address | ||
689 | */ | ||
690 | static int board_get_mac_address(u8 *mac) | ||
691 | { | ||
692 | u8 *p; | ||
693 | int count; | ||
694 | |||
695 | if (mac_addr_used >= nvram.mac_addr_count) { | ||
696 | printk(KERN_ERR PFX "not enough mac address\n"); | ||
697 | return -ENODEV; | ||
698 | } | ||
699 | |||
700 | memcpy(mac, nvram.mac_addr_base, ETH_ALEN); | ||
701 | p = mac + ETH_ALEN - 1; | ||
702 | count = mac_addr_used; | ||
703 | |||
704 | while (count--) { | ||
705 | do { | ||
706 | (*p)++; | ||
707 | if (*p != 0) | ||
708 | break; | ||
709 | p--; | ||
710 | } while (p != mac); | ||
711 | } | ||
712 | |||
713 | if (p == mac) { | ||
714 | printk(KERN_ERR PFX "unable to fetch mac address\n"); | ||
715 | return -ENODEV; | ||
716 | } | ||
717 | |||
718 | mac_addr_used++; | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | static struct mtd_partition mtd_partitions[] = { | 817 | static struct mtd_partition mtd_partitions[] = { |
723 | { | 818 | { |
724 | .name = "cfe", | 819 | .name = "cfe", |
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = { | |||
750 | }, | 845 | }, |
751 | }; | 846 | }; |
752 | 847 | ||
753 | /* | ||
754 | * Register a sane SPROMv2 to make the on-board | ||
755 | * bcm4318 WLAN work | ||
756 | */ | ||
757 | #ifdef CONFIG_SSB_PCIHOST | ||
758 | static struct ssb_sprom bcm63xx_sprom = { | ||
759 | .revision = 0x02, | ||
760 | .board_rev = 0x17, | ||
761 | .country_code = 0x0, | ||
762 | .ant_available_bg = 0x3, | ||
763 | .pa0b0 = 0x15ae, | ||
764 | .pa0b1 = 0xfa85, | ||
765 | .pa0b2 = 0xfe8d, | ||
766 | .pa1b0 = 0xffff, | ||
767 | .pa1b1 = 0xffff, | ||
768 | .pa1b2 = 0xffff, | ||
769 | .gpio0 = 0xff, | ||
770 | .gpio1 = 0xff, | ||
771 | .gpio2 = 0xff, | ||
772 | .gpio3 = 0xff, | ||
773 | .maxpwr_bg = 0x004c, | ||
774 | .itssi_bg = 0x00, | ||
775 | .boardflags_lo = 0x2848, | ||
776 | .boardflags_hi = 0x0000, | ||
777 | }; | ||
778 | #endif | ||
779 | |||
780 | static struct gpio_led_platform_data bcm63xx_led_data; | 848 | static struct gpio_led_platform_data bcm63xx_led_data; |
781 | 849 | ||
782 | static struct platform_device bcm63xx_gpio_leds = { | 850 | static struct platform_device bcm63xx_gpio_leds = { |
@@ -792,6 +860,12 @@ int __init board_register_devices(void) | |||
792 | { | 860 | { |
793 | u32 val; | 861 | u32 val; |
794 | 862 | ||
863 | if (board.has_uart0) | ||
864 | bcm63xx_uart_register(0); | ||
865 | |||
866 | if (board.has_uart1) | ||
867 | bcm63xx_uart_register(1); | ||
868 | |||
795 | if (board.has_pccard) | 869 | if (board.has_pccard) |
796 | bcm63xx_pcmcia_register(); | 870 | bcm63xx_pcmcia_register(); |
797 | 871 | ||
@@ -806,17 +880,6 @@ int __init board_register_devices(void) | |||
806 | if (board.has_dsp) | 880 | if (board.has_dsp) |
807 | bcm63xx_dsp_register(&board.dsp); | 881 | bcm63xx_dsp_register(&board.dsp); |
808 | 882 | ||
809 | /* Generate MAC address for WLAN and | ||
810 | * register our SPROM */ | ||
811 | #ifdef CONFIG_SSB_PCIHOST | ||
812 | if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { | ||
813 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); | ||
814 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); | ||
815 | if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0) | ||
816 | printk(KERN_ERR "failed to register fallback SPROM\n"); | ||
817 | } | ||
818 | #endif | ||
819 | |||
820 | /* read base address of boot chip select (0) */ | 883 | /* read base address of boot chip select (0) */ |
821 | if (BCMCPU_IS_6345()) | 884 | if (BCMCPU_IS_6345()) |
822 | val = 0x1fc00000; | 885 | val = 0x1fc00000; |
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 70378bb5e3f9..cbb7caf86d77 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = { | |||
36 | [RSET_TIMER] = BCM_6338_TIMER_BASE, | 36 | [RSET_TIMER] = BCM_6338_TIMER_BASE, |
37 | [RSET_WDT] = BCM_6338_WDT_BASE, | 37 | [RSET_WDT] = BCM_6338_WDT_BASE, |
38 | [RSET_UART0] = BCM_6338_UART0_BASE, | 38 | [RSET_UART0] = BCM_6338_UART0_BASE, |
39 | [RSET_UART1] = BCM_6338_UART1_BASE, | ||
39 | [RSET_GPIO] = BCM_6338_GPIO_BASE, | 40 | [RSET_GPIO] = BCM_6338_GPIO_BASE, |
40 | [RSET_SPI] = BCM_6338_SPI_BASE, | 41 | [RSET_SPI] = BCM_6338_SPI_BASE, |
41 | [RSET_OHCI0] = BCM_6338_OHCI0_BASE, | 42 | [RSET_OHCI0] = BCM_6338_OHCI0_BASE, |
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = { | |||
72 | [RSET_TIMER] = BCM_6345_TIMER_BASE, | 73 | [RSET_TIMER] = BCM_6345_TIMER_BASE, |
73 | [RSET_WDT] = BCM_6345_WDT_BASE, | 74 | [RSET_WDT] = BCM_6345_WDT_BASE, |
74 | [RSET_UART0] = BCM_6345_UART0_BASE, | 75 | [RSET_UART0] = BCM_6345_UART0_BASE, |
76 | [RSET_UART1] = BCM_6345_UART1_BASE, | ||
75 | [RSET_GPIO] = BCM_6345_GPIO_BASE, | 77 | [RSET_GPIO] = BCM_6345_GPIO_BASE, |
76 | [RSET_SPI] = BCM_6345_SPI_BASE, | 78 | [RSET_SPI] = BCM_6345_SPI_BASE, |
77 | [RSET_UDC0] = BCM_6345_UDC0_BASE, | 79 | [RSET_UDC0] = BCM_6345_UDC0_BASE, |
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = { | |||
109 | [RSET_TIMER] = BCM_6348_TIMER_BASE, | 111 | [RSET_TIMER] = BCM_6348_TIMER_BASE, |
110 | [RSET_WDT] = BCM_6348_WDT_BASE, | 112 | [RSET_WDT] = BCM_6348_WDT_BASE, |
111 | [RSET_UART0] = BCM_6348_UART0_BASE, | 113 | [RSET_UART0] = BCM_6348_UART0_BASE, |
114 | [RSET_UART1] = BCM_6348_UART1_BASE, | ||
112 | [RSET_GPIO] = BCM_6348_GPIO_BASE, | 115 | [RSET_GPIO] = BCM_6348_GPIO_BASE, |
113 | [RSET_SPI] = BCM_6348_SPI_BASE, | 116 | [RSET_SPI] = BCM_6348_SPI_BASE, |
114 | [RSET_OHCI0] = BCM_6348_OHCI0_BASE, | 117 | [RSET_OHCI0] = BCM_6348_OHCI0_BASE, |
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = { | |||
150 | [RSET_TIMER] = BCM_6358_TIMER_BASE, | 153 | [RSET_TIMER] = BCM_6358_TIMER_BASE, |
151 | [RSET_WDT] = BCM_6358_WDT_BASE, | 154 | [RSET_WDT] = BCM_6358_WDT_BASE, |
152 | [RSET_UART0] = BCM_6358_UART0_BASE, | 155 | [RSET_UART0] = BCM_6358_UART0_BASE, |
156 | [RSET_UART1] = BCM_6358_UART1_BASE, | ||
153 | [RSET_GPIO] = BCM_6358_GPIO_BASE, | 157 | [RSET_GPIO] = BCM_6358_GPIO_BASE, |
154 | [RSET_SPI] = BCM_6358_SPI_BASE, | 158 | [RSET_SPI] = BCM_6358_SPI_BASE, |
155 | [RSET_OHCI0] = BCM_6358_OHCI0_BASE, | 159 | [RSET_OHCI0] = BCM_6358_OHCI0_BASE, |
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = { | |||
170 | static const int bcm96358_irqs[] = { | 174 | static const int bcm96358_irqs[] = { |
171 | [IRQ_TIMER] = BCM_6358_TIMER_IRQ, | 175 | [IRQ_TIMER] = BCM_6358_TIMER_IRQ, |
172 | [IRQ_UART0] = BCM_6358_UART0_IRQ, | 176 | [IRQ_UART0] = BCM_6358_UART0_IRQ, |
177 | [IRQ_UART1] = BCM_6358_UART1_IRQ, | ||
173 | [IRQ_DSL] = BCM_6358_DSL_IRQ, | 178 | [IRQ_DSL] = BCM_6358_DSL_IRQ, |
174 | [IRQ_ENET0] = BCM_6358_ENET0_IRQ, | 179 | [IRQ_ENET0] = BCM_6358_ENET0_IRQ, |
175 | [IRQ_ENET1] = BCM_6358_ENET1_IRQ, | 180 | [IRQ_ENET1] = BCM_6358_ENET1_IRQ, |
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c index b0519461ad9b..c2963da0253e 100644 --- a/arch/mips/bcm63xx/dev-uart.c +++ b/arch/mips/bcm63xx/dev-uart.c | |||
@@ -11,31 +11,65 @@ | |||
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <bcm63xx_cpu.h> | 12 | #include <bcm63xx_cpu.h> |
13 | 13 | ||
14 | static struct resource uart_resources[] = { | 14 | static struct resource uart0_resources[] = { |
15 | { | 15 | { |
16 | .start = -1, /* filled at runtime */ | 16 | /* start & end filled at runtime */ |
17 | .end = -1, /* filled at runtime */ | ||
18 | .flags = IORESOURCE_MEM, | 17 | .flags = IORESOURCE_MEM, |
19 | }, | 18 | }, |
20 | { | 19 | { |
21 | .start = -1, /* filled at runtime */ | 20 | /* start filled at runtime */ |
22 | .flags = IORESOURCE_IRQ, | 21 | .flags = IORESOURCE_IRQ, |
23 | }, | 22 | }, |
24 | }; | 23 | }; |
25 | 24 | ||
26 | static struct platform_device bcm63xx_uart_device = { | 25 | static struct resource uart1_resources[] = { |
27 | .name = "bcm63xx_uart", | 26 | { |
28 | .id = 0, | 27 | /* start & end filled at runtime */ |
29 | .num_resources = ARRAY_SIZE(uart_resources), | 28 | .flags = IORESOURCE_MEM, |
30 | .resource = uart_resources, | 29 | }, |
30 | { | ||
31 | /* start filled at runtime */ | ||
32 | .flags = IORESOURCE_IRQ, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static struct platform_device bcm63xx_uart_devices[] = { | ||
37 | { | ||
38 | .name = "bcm63xx_uart", | ||
39 | .id = 0, | ||
40 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
41 | .resource = uart0_resources, | ||
42 | }, | ||
43 | |||
44 | { | ||
45 | .name = "bcm63xx_uart", | ||
46 | .id = 1, | ||
47 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
48 | .resource = uart1_resources, | ||
49 | } | ||
31 | }; | 50 | }; |
32 | 51 | ||
33 | int __init bcm63xx_uart_register(void) | 52 | int __init bcm63xx_uart_register(unsigned int id) |
34 | { | 53 | { |
35 | uart_resources[0].start = bcm63xx_regset_address(RSET_UART0); | 54 | if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) |
36 | uart_resources[0].end = uart_resources[0].start; | 55 | return -ENODEV; |
37 | uart_resources[0].end += RSET_UART_SIZE - 1; | 56 | |
38 | uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); | 57 | if (id == 1 && !BCMCPU_IS_6358()) |
39 | return platform_device_register(&bcm63xx_uart_device); | 58 | return -ENODEV; |
59 | |||
60 | if (id == 0) { | ||
61 | uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0); | ||
62 | uart0_resources[0].end = uart0_resources[0].start + | ||
63 | RSET_UART_SIZE - 1; | ||
64 | uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); | ||
65 | } | ||
66 | |||
67 | if (id == 1) { | ||
68 | uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1); | ||
69 | uart1_resources[0].end = uart1_resources[0].start + | ||
70 | RSET_UART_SIZE - 1; | ||
71 | uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1); | ||
72 | } | ||
73 | |||
74 | return platform_device_register(&bcm63xx_uart_devices[id]); | ||
40 | } | 75 | } |
41 | arch_initcall(bcm63xx_uart_register); | ||
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c index 87ca39046334..315bc7f79ce1 100644 --- a/arch/mips/bcm63xx/gpio.c +++ b/arch/mips/bcm63xx/gpio.c | |||
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = { | |||
125 | 125 | ||
126 | int __init bcm63xx_gpio_init(void) | 126 | int __init bcm63xx_gpio_init(void) |
127 | { | 127 | { |
128 | gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG); | ||
129 | gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG); | ||
128 | bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); | 130 | bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); |
129 | pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); | 131 | pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); |
130 | 132 | ||
131 | return gpiochip_add(&bcm63xx_gpio_chip); | 133 | return gpiochip_add(&bcm63xx_gpio_chip); |
132 | } | 134 | } |
133 | |||
134 | arch_initcall(bcm63xx_gpio_init); | ||
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index b321d3b16877..9a06fa9f9f0c 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops; | |||
45 | extern void pci_console_init(const char *arg); | 45 | extern void pci_console_init(const char *arg); |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #ifdef CONFIG_CAVIUM_RESERVE32 | ||
49 | extern uint64_t octeon_reserve32_memory; | ||
50 | #endif | ||
51 | static unsigned long long MAX_MEMORY = 512ull << 20; | 48 | static unsigned long long MAX_MEMORY = 512ull << 20; |
52 | 49 | ||
53 | struct octeon_boot_descriptor *octeon_boot_desc_ptr; | 50 | struct octeon_boot_descriptor *octeon_boot_desc_ptr; |
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void) | |||
186 | write_octeon_c0_dcacheerr(0); | 183 | write_octeon_c0_dcacheerr(0); |
187 | } | 184 | } |
188 | 185 | ||
189 | #ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB | ||
190 | /** | ||
191 | * Called on every core to setup the wired tlb entry needed | ||
192 | * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set. | ||
193 | * | ||
194 | */ | ||
195 | static void octeon_hal_setup_per_cpu_reserved32(void *unused) | ||
196 | { | ||
197 | /* | ||
198 | * The config has selected to wire the reserve32 memory for all | ||
199 | * userspace applications. We need to put a wired TLB entry in for each | ||
200 | * 512MB of reserve32 memory. We only handle double 256MB pages here, | ||
201 | * so reserve32 must be multiple of 512MB. | ||
202 | */ | ||
203 | uint32_t size = CONFIG_CAVIUM_RESERVE32; | ||
204 | uint32_t entrylo0 = | ||
205 | 0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6); | ||
206 | uint32_t entrylo1 = entrylo0 + (256 << 14); | ||
207 | uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20)); | ||
208 | while (size >= 512) { | ||
209 | #if 0 | ||
210 | pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n", | ||
211 | smp_processor_id(), entryhi); | ||
212 | #endif | ||
213 | add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M); | ||
214 | entrylo0 += 512 << 14; | ||
215 | entrylo1 += 512 << 14; | ||
216 | entryhi += 512 << 20; | ||
217 | size -= 512; | ||
218 | } | ||
219 | } | ||
220 | #endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */ | ||
221 | |||
222 | /** | ||
223 | * Called to release the named block which was used to made sure | ||
224 | * that nobody used the memory for something else during | ||
225 | * init. Now we'll free it so userspace apps can use this | ||
226 | * memory region with bootmem_alloc. | ||
227 | * | ||
228 | * This function is called only once from prom_free_prom_memory(). | ||
229 | */ | ||
230 | void octeon_hal_setup_reserved32(void) | ||
231 | { | ||
232 | #ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB | ||
233 | on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1); | ||
234 | #endif | ||
235 | } | ||
236 | |||
237 | /** | 186 | /** |
238 | * Reboot Octeon | 187 | * Reboot Octeon |
239 | * | 188 | * |
@@ -294,18 +243,6 @@ static void octeon_halt(void) | |||
294 | octeon_kill_core(NULL); | 243 | octeon_kill_core(NULL); |
295 | } | 244 | } |
296 | 245 | ||
297 | #if 0 | ||
298 | /** | ||
299 | * Platform time init specifics. | ||
300 | * Returns | ||
301 | */ | ||
302 | void __init plat_time_init(void) | ||
303 | { | ||
304 | /* Nothing special here, but we are required to have one */ | ||
305 | } | ||
306 | |||
307 | #endif | ||
308 | |||
309 | /** | 246 | /** |
310 | * Handle all the error condition interrupts that might occur. | 247 | * Handle all the error condition interrupts that might occur. |
311 | * | 248 | * |
@@ -502,25 +439,13 @@ void __init prom_init(void) | |||
502 | * memory when it is getting memory from the | 439 | * memory when it is getting memory from the |
503 | * bootloader. Later, after the memory allocations are | 440 | * bootloader. Later, after the memory allocations are |
504 | * complete, the reserve32 will be freed. | 441 | * complete, the reserve32 will be freed. |
505 | */ | 442 | * |
506 | #ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB | ||
507 | if (CONFIG_CAVIUM_RESERVE32 & 0x1ff) | ||
508 | pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. " | ||
509 | "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB " | ||
510 | "is set\n"); | ||
511 | else | ||
512 | addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, | ||
513 | 0, 0, 512 << 20, | ||
514 | "CAVIUM_RESERVE32", 0); | ||
515 | #else | ||
516 | /* | ||
517 | * Allocate memory for RESERVED32 aligned on 2MB boundary. This | 443 | * Allocate memory for RESERVED32 aligned on 2MB boundary. This |
518 | * is in case we later use hugetlb entries with it. | 444 | * is in case we later use hugetlb entries with it. |
519 | */ | 445 | */ |
520 | addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, | 446 | addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, |
521 | 0, 0, 2 << 20, | 447 | 0, 0, 2 << 20, |
522 | "CAVIUM_RESERVE32", 0); | 448 | "CAVIUM_RESERVE32", 0); |
523 | #endif | ||
524 | if (addr < 0) | 449 | if (addr < 0) |
525 | pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n"); | 450 | pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n"); |
526 | else | 451 | else |
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void) | |||
817 | panic("Unable to request_irq(OCTEON_IRQ_RML)\n"); | 742 | panic("Unable to request_irq(OCTEON_IRQ_RML)\n"); |
818 | } | 743 | } |
819 | #endif | 744 | #endif |
820 | |||
821 | /* This call is here so that it is performed after any TLB | ||
822 | initializations. It needs to be after these in case the | ||
823 | CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */ | ||
824 | octeon_hal_setup_reserved32(); | ||
825 | } | 745 | } |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 51e980290ce1..6d99b9d8887d 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu) | |||
279 | uint32_t avail_coremask; | 279 | uint32_t avail_coremask; |
280 | struct cvmx_bootmem_named_block_desc *block_desc; | 280 | struct cvmx_bootmem_named_block_desc *block_desc; |
281 | 281 | ||
282 | #ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG | ||
283 | /* Disable the watchdog */ | ||
284 | cvmx_ciu_wdogx_t ciu_wdog; | ||
285 | ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu)); | ||
286 | ciu_wdog.s.mode = 0; | ||
287 | cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64); | ||
288 | #endif | ||
289 | |||
290 | while (per_cpu(cpu_state, cpu) != CPU_DEAD) | 282 | while (per_cpu(cpu_state, cpu) != CPU_DEAD) |
291 | cpu_relax(); | 283 | cpu_relax(); |
292 | 284 | ||
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index c2f06e38c854..0583bb29150f 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.26-rc8 | 3 | # Linux kernel version: 2.6.34-rc3 |
4 | # Wed Jul 2 17:02:55 2008 | 4 | # Sat Apr 3 16:32:11 2010 |
5 | # | 5 | # |
6 | CONFIG_MIPS=y | 6 | CONFIG_MIPS=y |
7 | 7 | ||
@@ -9,20 +9,25 @@ CONFIG_MIPS=y | |||
9 | # Machine selection | 9 | # Machine selection |
10 | # | 10 | # |
11 | # CONFIG_MACH_ALCHEMY is not set | 11 | # CONFIG_MACH_ALCHEMY is not set |
12 | # CONFIG_AR7 is not set | ||
12 | # CONFIG_BCM47XX is not set | 13 | # CONFIG_BCM47XX is not set |
14 | # CONFIG_BCM63XX is not set | ||
13 | # CONFIG_MIPS_COBALT is not set | 15 | # CONFIG_MIPS_COBALT is not set |
14 | # CONFIG_MACH_DECSTATION is not set | 16 | # CONFIG_MACH_DECSTATION is not set |
15 | # CONFIG_MACH_JAZZ is not set | 17 | # CONFIG_MACH_JAZZ is not set |
16 | # CONFIG_LASAT is not set | 18 | # CONFIG_LASAT is not set |
17 | # CONFIG_LEMOTE_FULONG is not set | 19 | # CONFIG_MACH_LOONGSON is not set |
18 | # CONFIG_MIPS_MALTA is not set | 20 | # CONFIG_MIPS_MALTA is not set |
19 | # CONFIG_MIPS_SIM is not set | 21 | # CONFIG_MIPS_SIM is not set |
20 | # CONFIG_MARKEINS is not set | 22 | # CONFIG_NEC_MARKEINS is not set |
21 | # CONFIG_MACH_VR41XX is not set | 23 | # CONFIG_MACH_VR41XX is not set |
24 | # CONFIG_NXP_STB220 is not set | ||
25 | # CONFIG_NXP_STB225 is not set | ||
22 | # CONFIG_PNX8550_JBS is not set | 26 | # CONFIG_PNX8550_JBS is not set |
23 | # CONFIG_PNX8550_STB810 is not set | 27 | # CONFIG_PNX8550_STB810 is not set |
24 | # CONFIG_PMC_MSP is not set | 28 | # CONFIG_PMC_MSP is not set |
25 | # CONFIG_PMC_YOSEMITE is not set | 29 | # CONFIG_PMC_YOSEMITE is not set |
30 | # CONFIG_POWERTV is not set | ||
26 | # CONFIG_SGI_IP22 is not set | 31 | # CONFIG_SGI_IP22 is not set |
27 | # CONFIG_SGI_IP27 is not set | 32 | # CONFIG_SGI_IP27 is not set |
28 | # CONFIG_SGI_IP28 is not set | 33 | # CONFIG_SGI_IP28 is not set |
@@ -36,10 +41,13 @@ CONFIG_MIPS=y | |||
36 | # CONFIG_SIBYTE_SENTOSA is not set | 41 | # CONFIG_SIBYTE_SENTOSA is not set |
37 | CONFIG_SIBYTE_BIGSUR=y | 42 | CONFIG_SIBYTE_BIGSUR=y |
38 | # CONFIG_SNI_RM is not set | 43 | # CONFIG_SNI_RM is not set |
39 | # CONFIG_TOSHIBA_JMR3927 is not set | 44 | # CONFIG_MACH_TX39XX is not set |
40 | # CONFIG_TOSHIBA_RBTX4927 is not set | 45 | # CONFIG_MACH_TX49XX is not set |
41 | # CONFIG_TOSHIBA_RBTX4938 is not set | 46 | # CONFIG_MIKROTIK_RB532 is not set |
42 | # CONFIG_WR_PPMC is not set | 47 | # CONFIG_WR_PPMC is not set |
48 | # CONFIG_CAVIUM_OCTEON_SIMULATOR is not set | ||
49 | # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set | ||
50 | # CONFIG_ALCHEMY_GPIO_INDIRECT is not set | ||
43 | CONFIG_SIBYTE_BCM1x80=y | 51 | CONFIG_SIBYTE_BCM1x80=y |
44 | CONFIG_SIBYTE_SB1xxx_SOC=y | 52 | CONFIG_SIBYTE_SB1xxx_SOC=y |
45 | # CONFIG_CPU_SB1_PASS_1 is not set | 53 | # CONFIG_CPU_SB1_PASS_1 is not set |
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y | |||
48 | # CONFIG_CPU_SB1_PASS_4 is not set | 56 | # CONFIG_CPU_SB1_PASS_4 is not set |
49 | # CONFIG_CPU_SB1_PASS_2_112x is not set | 57 | # CONFIG_CPU_SB1_PASS_2_112x is not set |
50 | # CONFIG_CPU_SB1_PASS_3 is not set | 58 | # CONFIG_CPU_SB1_PASS_3 is not set |
51 | # CONFIG_SIMULATION is not set | ||
52 | # CONFIG_SB1_CEX_ALWAYS_FATAL is not set | 59 | # CONFIG_SB1_CEX_ALWAYS_FATAL is not set |
53 | # CONFIG_SB1_CERR_STALL is not set | 60 | # CONFIG_SB1_CERR_STALL is not set |
54 | CONFIG_SIBYTE_CFE=y | ||
55 | # CONFIG_SIBYTE_CFE_CONSOLE is not set | 61 | # CONFIG_SIBYTE_CFE_CONSOLE is not set |
56 | # CONFIG_SIBYTE_BUS_WATCHER is not set | 62 | # CONFIG_SIBYTE_BUS_WATCHER is not set |
57 | # CONFIG_SIBYTE_TBPROF is not set | 63 | # CONFIG_SIBYTE_TBPROF is not set |
58 | CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y | 64 | CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y |
65 | CONFIG_LOONGSON_UART_BASE=y | ||
59 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 66 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
60 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | 67 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set |
61 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 68 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y | |||
66 | CONFIG_GENERIC_CLOCKEVENTS=y | 73 | CONFIG_GENERIC_CLOCKEVENTS=y |
67 | CONFIG_GENERIC_TIME=y | 74 | CONFIG_GENERIC_TIME=y |
68 | CONFIG_GENERIC_CMOS_UPDATE=y | 75 | CONFIG_GENERIC_CMOS_UPDATE=y |
69 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | 76 | CONFIG_SCHED_OMIT_FRAME_POINTER=y |
70 | # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set | 77 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y |
71 | CONFIG_CEVT_BCM1480=y | 78 | CONFIG_CEVT_BCM1480=y |
72 | CONFIG_CSRC_BCM1480=y | 79 | CONFIG_CSRC_BCM1480=y |
73 | CONFIG_CFE=y | 80 | CONFIG_CFE=y |
74 | CONFIG_DMA_COHERENT=y | 81 | CONFIG_DMA_COHERENT=y |
75 | CONFIG_EARLY_PRINTK=y | ||
76 | CONFIG_SYS_HAS_EARLY_PRINTK=y | 82 | CONFIG_SYS_HAS_EARLY_PRINTK=y |
77 | # CONFIG_HOTPLUG_CPU is not set | ||
78 | # CONFIG_NO_IOPORT is not set | 83 | # CONFIG_NO_IOPORT is not set |
79 | CONFIG_CPU_BIG_ENDIAN=y | 84 | CONFIG_CPU_BIG_ENDIAN=y |
80 | # CONFIG_CPU_LITTLE_ENDIAN is not set | 85 | # CONFIG_CPU_LITTLE_ENDIAN is not set |
@@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 | |||
88 | # | 93 | # |
89 | # CPU selection | 94 | # CPU selection |
90 | # | 95 | # |
91 | # CONFIG_CPU_LOONGSON2 is not set | 96 | # CONFIG_CPU_LOONGSON2E is not set |
97 | # CONFIG_CPU_LOONGSON2F is not set | ||
92 | # CONFIG_CPU_MIPS32_R1 is not set | 98 | # CONFIG_CPU_MIPS32_R1 is not set |
93 | # CONFIG_CPU_MIPS32_R2 is not set | 99 | # CONFIG_CPU_MIPS32_R2 is not set |
94 | # CONFIG_CPU_MIPS64_R1 is not set | 100 | # CONFIG_CPU_MIPS64_R1 is not set |
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 | |||
101 | # CONFIG_CPU_TX49XX is not set | 107 | # CONFIG_CPU_TX49XX is not set |
102 | # CONFIG_CPU_R5000 is not set | 108 | # CONFIG_CPU_R5000 is not set |
103 | # CONFIG_CPU_R5432 is not set | 109 | # CONFIG_CPU_R5432 is not set |
110 | # CONFIG_CPU_R5500 is not set | ||
104 | # CONFIG_CPU_R6000 is not set | 111 | # CONFIG_CPU_R6000 is not set |
105 | # CONFIG_CPU_NEVADA is not set | 112 | # CONFIG_CPU_NEVADA is not set |
106 | # CONFIG_CPU_R8000 is not set | 113 | # CONFIG_CPU_R8000 is not set |
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 | |||
108 | # CONFIG_CPU_RM7000 is not set | 115 | # CONFIG_CPU_RM7000 is not set |
109 | # CONFIG_CPU_RM9000 is not set | 116 | # CONFIG_CPU_RM9000 is not set |
110 | CONFIG_CPU_SB1=y | 117 | CONFIG_CPU_SB1=y |
118 | # CONFIG_CPU_CAVIUM_OCTEON is not set | ||
111 | CONFIG_SYS_HAS_CPU_SB1=y | 119 | CONFIG_SYS_HAS_CPU_SB1=y |
112 | CONFIG_WEAK_ORDERING=y | 120 | CONFIG_WEAK_ORDERING=y |
113 | CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y | 121 | CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y |
@@ -123,11 +131,13 @@ CONFIG_64BIT=y | |||
123 | CONFIG_PAGE_SIZE_4KB=y | 131 | CONFIG_PAGE_SIZE_4KB=y |
124 | # CONFIG_PAGE_SIZE_8KB is not set | 132 | # CONFIG_PAGE_SIZE_8KB is not set |
125 | # CONFIG_PAGE_SIZE_16KB is not set | 133 | # CONFIG_PAGE_SIZE_16KB is not set |
134 | # CONFIG_PAGE_SIZE_32KB is not set | ||
126 | # CONFIG_PAGE_SIZE_64KB is not set | 135 | # CONFIG_PAGE_SIZE_64KB is not set |
127 | # CONFIG_SIBYTE_DMA_PAGEOPS is not set | 136 | # CONFIG_SIBYTE_DMA_PAGEOPS is not set |
128 | CONFIG_MIPS_MT_DISABLED=y | 137 | CONFIG_MIPS_MT_DISABLED=y |
129 | # CONFIG_MIPS_MT_SMP is not set | 138 | # CONFIG_MIPS_MT_SMP is not set |
130 | # CONFIG_MIPS_MT_SMTC is not set | 139 | # CONFIG_MIPS_MT_SMTC is not set |
140 | # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set | ||
131 | CONFIG_CPU_HAS_SYNC=y | 141 | CONFIG_CPU_HAS_SYNC=y |
132 | CONFIG_GENERIC_HARDIRQS=y | 142 | CONFIG_GENERIC_HARDIRQS=y |
133 | CONFIG_GENERIC_IRQ_PROBE=y | 143 | CONFIG_GENERIC_IRQ_PROBE=y |
@@ -142,18 +152,17 @@ CONFIG_FLATMEM_MANUAL=y | |||
142 | # CONFIG_SPARSEMEM_MANUAL is not set | 152 | # CONFIG_SPARSEMEM_MANUAL is not set |
143 | CONFIG_FLATMEM=y | 153 | CONFIG_FLATMEM=y |
144 | CONFIG_FLAT_NODE_MEM_MAP=y | 154 | CONFIG_FLAT_NODE_MEM_MAP=y |
145 | # CONFIG_SPARSEMEM_STATIC is not set | ||
146 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
147 | CONFIG_PAGEFLAGS_EXTENDED=y | 155 | CONFIG_PAGEFLAGS_EXTENDED=y |
148 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 156 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
149 | CONFIG_RESOURCES_64BIT=y | 157 | CONFIG_PHYS_ADDR_T_64BIT=y |
150 | CONFIG_ZONE_DMA_FLAG=0 | 158 | CONFIG_ZONE_DMA_FLAG=0 |
151 | CONFIG_VIRT_TO_BUS=y | 159 | CONFIG_VIRT_TO_BUS=y |
160 | # CONFIG_KSM is not set | ||
161 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
152 | CONFIG_SMP=y | 162 | CONFIG_SMP=y |
153 | CONFIG_SYS_SUPPORTS_SMP=y | 163 | CONFIG_SYS_SUPPORTS_SMP=y |
154 | CONFIG_NR_CPUS_DEFAULT_4=y | 164 | CONFIG_NR_CPUS_DEFAULT_4=y |
155 | CONFIG_NR_CPUS=4 | 165 | CONFIG_NR_CPUS=4 |
156 | # CONFIG_MIPS_CMP is not set | ||
157 | CONFIG_TICK_ONESHOT=y | 166 | CONFIG_TICK_ONESHOT=y |
158 | CONFIG_NO_HZ=y | 167 | CONFIG_NO_HZ=y |
159 | CONFIG_HIGH_RES_TIMERS=y | 168 | CONFIG_HIGH_RES_TIMERS=y |
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y | |||
175 | CONFIG_LOCKDEP_SUPPORT=y | 184 | CONFIG_LOCKDEP_SUPPORT=y |
176 | CONFIG_STACKTRACE_SUPPORT=y | 185 | CONFIG_STACKTRACE_SUPPORT=y |
177 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 186 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
187 | CONFIG_CONSTRUCTORS=y | ||
178 | 188 | ||
179 | # | 189 | # |
180 | # General setup | 190 | # General setup |
@@ -188,6 +198,7 @@ CONFIG_SWAP=y | |||
188 | CONFIG_SYSVIPC=y | 198 | CONFIG_SYSVIPC=y |
189 | CONFIG_SYSVIPC_SYSCTL=y | 199 | CONFIG_SYSVIPC_SYSCTL=y |
190 | CONFIG_POSIX_MQUEUE=y | 200 | CONFIG_POSIX_MQUEUE=y |
201 | CONFIG_POSIX_MQUEUE_SYSCTL=y | ||
191 | CONFIG_BSD_PROCESS_ACCT=y | 202 | CONFIG_BSD_PROCESS_ACCT=y |
192 | CONFIG_BSD_PROCESS_ACCT_V3=y | 203 | CONFIG_BSD_PROCESS_ACCT_V3=y |
193 | CONFIG_TASKSTATS=y | 204 | CONFIG_TASKSTATS=y |
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y | |||
195 | CONFIG_TASK_XACCT=y | 206 | CONFIG_TASK_XACCT=y |
196 | CONFIG_TASK_IO_ACCOUNTING=y | 207 | CONFIG_TASK_IO_ACCOUNTING=y |
197 | CONFIG_AUDIT=y | 208 | CONFIG_AUDIT=y |
209 | |||
210 | # | ||
211 | # RCU Subsystem | ||
212 | # | ||
213 | CONFIG_TREE_RCU=y | ||
214 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
215 | # CONFIG_TINY_RCU is not set | ||
216 | # CONFIG_RCU_TRACE is not set | ||
217 | CONFIG_RCU_FANOUT=64 | ||
218 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
219 | # CONFIG_RCU_FAST_NO_HZ is not set | ||
220 | # CONFIG_TREE_RCU_TRACE is not set | ||
198 | CONFIG_IKCONFIG=y | 221 | CONFIG_IKCONFIG=y |
199 | CONFIG_IKCONFIG_PROC=y | 222 | CONFIG_IKCONFIG_PROC=y |
200 | CONFIG_LOG_BUF_SHIFT=16 | 223 | CONFIG_LOG_BUF_SHIFT=16 |
201 | # CONFIG_CGROUPS is not set | 224 | # CONFIG_CGROUPS is not set |
202 | CONFIG_GROUP_SCHED=y | 225 | # CONFIG_SYSFS_DEPRECATED_V2 is not set |
203 | CONFIG_FAIR_GROUP_SCHED=y | ||
204 | # CONFIG_RT_GROUP_SCHED is not set | ||
205 | CONFIG_USER_SCHED=y | ||
206 | # CONFIG_CGROUP_SCHED is not set | ||
207 | CONFIG_SYSFS_DEPRECATED=y | ||
208 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
209 | CONFIG_RELAY=y | 226 | CONFIG_RELAY=y |
210 | # CONFIG_NAMESPACES is not set | 227 | CONFIG_NAMESPACES=y |
228 | CONFIG_UTS_NS=y | ||
229 | CONFIG_IPC_NS=y | ||
230 | CONFIG_USER_NS=y | ||
231 | CONFIG_PID_NS=y | ||
232 | CONFIG_NET_NS=y | ||
211 | CONFIG_BLK_DEV_INITRD=y | 233 | CONFIG_BLK_DEV_INITRD=y |
212 | CONFIG_INITRAMFS_SOURCE="" | 234 | CONFIG_INITRAMFS_SOURCE="" |
235 | CONFIG_RD_GZIP=y | ||
236 | # CONFIG_RD_BZIP2 is not set | ||
237 | # CONFIG_RD_LZMA is not set | ||
238 | # CONFIG_RD_LZO is not set | ||
213 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 239 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
214 | CONFIG_SYSCTL=y | 240 | CONFIG_SYSCTL=y |
241 | CONFIG_ANON_INODES=y | ||
215 | CONFIG_EMBEDDED=y | 242 | CONFIG_EMBEDDED=y |
216 | # CONFIG_SYSCTL_SYSCALL is not set | 243 | # CONFIG_SYSCTL_SYSCALL is not set |
217 | CONFIG_KALLSYMS=y | 244 | CONFIG_KALLSYMS=y |
@@ -222,29 +249,36 @@ CONFIG_PRINTK=y | |||
222 | CONFIG_BUG=y | 249 | CONFIG_BUG=y |
223 | CONFIG_ELF_CORE=y | 250 | CONFIG_ELF_CORE=y |
224 | # CONFIG_PCSPKR_PLATFORM is not set | 251 | # CONFIG_PCSPKR_PLATFORM is not set |
225 | CONFIG_COMPAT_BRK=y | ||
226 | CONFIG_BASE_FULL=y | 252 | CONFIG_BASE_FULL=y |
227 | CONFIG_FUTEX=y | 253 | CONFIG_FUTEX=y |
228 | CONFIG_ANON_INODES=y | ||
229 | CONFIG_EPOLL=y | 254 | CONFIG_EPOLL=y |
230 | CONFIG_SIGNALFD=y | 255 | CONFIG_SIGNALFD=y |
231 | CONFIG_TIMERFD=y | 256 | CONFIG_TIMERFD=y |
232 | CONFIG_EVENTFD=y | 257 | CONFIG_EVENTFD=y |
233 | CONFIG_SHMEM=y | 258 | CONFIG_SHMEM=y |
259 | CONFIG_AIO=y | ||
260 | |||
261 | # | ||
262 | # Kernel Performance Events And Counters | ||
263 | # | ||
234 | CONFIG_VM_EVENT_COUNTERS=y | 264 | CONFIG_VM_EVENT_COUNTERS=y |
265 | CONFIG_PCI_QUIRKS=y | ||
266 | CONFIG_COMPAT_BRK=y | ||
235 | CONFIG_SLAB=y | 267 | CONFIG_SLAB=y |
236 | # CONFIG_SLUB is not set | 268 | # CONFIG_SLUB is not set |
237 | # CONFIG_SLOB is not set | 269 | # CONFIG_SLOB is not set |
238 | # CONFIG_PROFILING is not set | 270 | # CONFIG_PROFILING is not set |
239 | # CONFIG_MARKERS is not set | ||
240 | CONFIG_HAVE_OPROFILE=y | 271 | CONFIG_HAVE_OPROFILE=y |
241 | # CONFIG_HAVE_KPROBES is not set | 272 | CONFIG_HAVE_SYSCALL_WRAPPERS=y |
242 | # CONFIG_HAVE_KRETPROBES is not set | 273 | CONFIG_USE_GENERIC_SMP_HELPERS=y |
243 | # CONFIG_HAVE_DMA_ATTRS is not set | 274 | |
244 | CONFIG_PROC_PAGE_MONITOR=y | 275 | # |
276 | # GCOV-based kernel profiling | ||
277 | # | ||
278 | # CONFIG_SLOW_WORK is not set | ||
279 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
245 | CONFIG_SLABINFO=y | 280 | CONFIG_SLABINFO=y |
246 | CONFIG_RT_MUTEXES=y | 281 | CONFIG_RT_MUTEXES=y |
247 | # CONFIG_TINY_SHMEM is not set | ||
248 | CONFIG_BASE_SMALL=0 | 282 | CONFIG_BASE_SMALL=0 |
249 | CONFIG_MODULES=y | 283 | CONFIG_MODULES=y |
250 | # CONFIG_MODULE_FORCE_LOAD is not set | 284 | # CONFIG_MODULE_FORCE_LOAD is not set |
@@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y | |||
252 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 286 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
253 | CONFIG_MODVERSIONS=y | 287 | CONFIG_MODVERSIONS=y |
254 | CONFIG_MODULE_SRCVERSION_ALL=y | 288 | CONFIG_MODULE_SRCVERSION_ALL=y |
255 | CONFIG_KMOD=y | ||
256 | CONFIG_STOP_MACHINE=y | 289 | CONFIG_STOP_MACHINE=y |
257 | CONFIG_BLOCK=y | 290 | CONFIG_BLOCK=y |
258 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
259 | # CONFIG_BLK_DEV_BSG is not set | 291 | # CONFIG_BLK_DEV_BSG is not set |
292 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
260 | CONFIG_BLOCK_COMPAT=y | 293 | CONFIG_BLOCK_COMPAT=y |
261 | 294 | ||
262 | # | 295 | # |
263 | # IO Schedulers | 296 | # IO Schedulers |
264 | # | 297 | # |
265 | CONFIG_IOSCHED_NOOP=y | 298 | CONFIG_IOSCHED_NOOP=y |
266 | CONFIG_IOSCHED_AS=y | ||
267 | CONFIG_IOSCHED_DEADLINE=y | 299 | CONFIG_IOSCHED_DEADLINE=y |
268 | CONFIG_IOSCHED_CFQ=y | 300 | CONFIG_IOSCHED_CFQ=y |
269 | CONFIG_DEFAULT_AS=y | ||
270 | # CONFIG_DEFAULT_DEADLINE is not set | 301 | # CONFIG_DEFAULT_DEADLINE is not set |
271 | # CONFIG_DEFAULT_CFQ is not set | 302 | CONFIG_DEFAULT_CFQ=y |
272 | # CONFIG_DEFAULT_NOOP is not set | 303 | # CONFIG_DEFAULT_NOOP is not set |
273 | CONFIG_DEFAULT_IOSCHED="anticipatory" | 304 | CONFIG_DEFAULT_IOSCHED="cfq" |
274 | CONFIG_CLASSIC_RCU=y | 305 | # CONFIG_INLINE_SPIN_TRYLOCK is not set |
306 | # CONFIG_INLINE_SPIN_TRYLOCK_BH is not set | ||
307 | # CONFIG_INLINE_SPIN_LOCK is not set | ||
308 | # CONFIG_INLINE_SPIN_LOCK_BH is not set | ||
309 | # CONFIG_INLINE_SPIN_LOCK_IRQ is not set | ||
310 | # CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set | ||
311 | CONFIG_INLINE_SPIN_UNLOCK=y | ||
312 | # CONFIG_INLINE_SPIN_UNLOCK_BH is not set | ||
313 | CONFIG_INLINE_SPIN_UNLOCK_IRQ=y | ||
314 | # CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set | ||
315 | # CONFIG_INLINE_READ_TRYLOCK is not set | ||
316 | # CONFIG_INLINE_READ_LOCK is not set | ||
317 | # CONFIG_INLINE_READ_LOCK_BH is not set | ||
318 | # CONFIG_INLINE_READ_LOCK_IRQ is not set | ||
319 | # CONFIG_INLINE_READ_LOCK_IRQSAVE is not set | ||
320 | CONFIG_INLINE_READ_UNLOCK=y | ||
321 | # CONFIG_INLINE_READ_UNLOCK_BH is not set | ||
322 | CONFIG_INLINE_READ_UNLOCK_IRQ=y | ||
323 | # CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set | ||
324 | # CONFIG_INLINE_WRITE_TRYLOCK is not set | ||
325 | # CONFIG_INLINE_WRITE_LOCK is not set | ||
326 | # CONFIG_INLINE_WRITE_LOCK_BH is not set | ||
327 | # CONFIG_INLINE_WRITE_LOCK_IRQ is not set | ||
328 | # CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set | ||
329 | CONFIG_INLINE_WRITE_UNLOCK=y | ||
330 | # CONFIG_INLINE_WRITE_UNLOCK_BH is not set | ||
331 | CONFIG_INLINE_WRITE_UNLOCK_IRQ=y | ||
332 | # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set | ||
333 | CONFIG_MUTEX_SPIN_ON_OWNER=y | ||
334 | # CONFIG_FREEZER is not set | ||
275 | 335 | ||
276 | # | 336 | # |
277 | # Bus options (PCI, PCMCIA, EISA, ISA, TC) | 337 | # Bus options (PCI, PCMCIA, EISA, ISA, TC) |
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y | |||
280 | CONFIG_PCI=y | 340 | CONFIG_PCI=y |
281 | CONFIG_PCI_DOMAINS=y | 341 | CONFIG_PCI_DOMAINS=y |
282 | # CONFIG_ARCH_SUPPORTS_MSI is not set | 342 | # CONFIG_ARCH_SUPPORTS_MSI is not set |
283 | CONFIG_PCI_LEGACY=y | ||
284 | CONFIG_PCI_DEBUG=y | 343 | CONFIG_PCI_DEBUG=y |
344 | # CONFIG_PCI_STUB is not set | ||
345 | # CONFIG_PCI_IOV is not set | ||
285 | CONFIG_MMU=y | 346 | CONFIG_MMU=y |
286 | CONFIG_ZONE_DMA32=y | 347 | CONFIG_ZONE_DMA32=y |
287 | # CONFIG_PCCARD is not set | 348 | # CONFIG_PCCARD is not set |
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y | |||
291 | # Executable file formats | 352 | # Executable file formats |
292 | # | 353 | # |
293 | CONFIG_BINFMT_ELF=y | 354 | CONFIG_BINFMT_ELF=y |
355 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
356 | # CONFIG_HAVE_AOUT is not set | ||
294 | # CONFIG_BINFMT_MISC is not set | 357 | # CONFIG_BINFMT_MISC is not set |
295 | CONFIG_MIPS32_COMPAT=y | 358 | CONFIG_MIPS32_COMPAT=y |
296 | CONFIG_COMPAT=y | 359 | CONFIG_COMPAT=y |
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y | |||
304 | # | 367 | # |
305 | CONFIG_PM=y | 368 | CONFIG_PM=y |
306 | # CONFIG_PM_DEBUG is not set | 369 | # CONFIG_PM_DEBUG is not set |
307 | 370 | # CONFIG_PM_RUNTIME is not set | |
308 | # | ||
309 | # Networking | ||
310 | # | ||
311 | CONFIG_NET=y | 371 | CONFIG_NET=y |
312 | 372 | ||
313 | # | 373 | # |
314 | # Networking options | 374 | # Networking options |
315 | # | 375 | # |
316 | CONFIG_PACKET=y | 376 | CONFIG_PACKET=y |
317 | CONFIG_PACKET_MMAP=y | ||
318 | CONFIG_UNIX=y | 377 | CONFIG_UNIX=y |
319 | CONFIG_XFRM=y | 378 | CONFIG_XFRM=y |
320 | CONFIG_XFRM_USER=m | 379 | CONFIG_XFRM_USER=m |
321 | # CONFIG_XFRM_SUB_POLICY is not set | 380 | # CONFIG_XFRM_SUB_POLICY is not set |
322 | CONFIG_XFRM_MIGRATE=y | 381 | CONFIG_XFRM_MIGRATE=y |
323 | # CONFIG_XFRM_STATISTICS is not set | 382 | # CONFIG_XFRM_STATISTICS is not set |
383 | CONFIG_XFRM_IPCOMP=m | ||
324 | CONFIG_NET_KEY=y | 384 | CONFIG_NET_KEY=y |
325 | CONFIG_NET_KEY_MIGRATE=y | 385 | CONFIG_NET_KEY_MIGRATE=y |
326 | CONFIG_INET=y | 386 | CONFIG_INET=y |
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y | |||
353 | CONFIG_TCP_CONG_CUBIC=y | 413 | CONFIG_TCP_CONG_CUBIC=y |
354 | CONFIG_DEFAULT_TCP_CONG="cubic" | 414 | CONFIG_DEFAULT_TCP_CONG="cubic" |
355 | CONFIG_TCP_MD5SIG=y | 415 | CONFIG_TCP_MD5SIG=y |
356 | CONFIG_IP_VS=m | ||
357 | # CONFIG_IP_VS_DEBUG is not set | ||
358 | CONFIG_IP_VS_TAB_BITS=12 | ||
359 | |||
360 | # | ||
361 | # IPVS transport protocol load balancing support | ||
362 | # | ||
363 | CONFIG_IP_VS_PROTO_TCP=y | ||
364 | CONFIG_IP_VS_PROTO_UDP=y | ||
365 | CONFIG_IP_VS_PROTO_ESP=y | ||
366 | CONFIG_IP_VS_PROTO_AH=y | ||
367 | |||
368 | # | ||
369 | # IPVS scheduler | ||
370 | # | ||
371 | CONFIG_IP_VS_RR=m | ||
372 | CONFIG_IP_VS_WRR=m | ||
373 | CONFIG_IP_VS_LC=m | ||
374 | CONFIG_IP_VS_WLC=m | ||
375 | CONFIG_IP_VS_LBLC=m | ||
376 | CONFIG_IP_VS_LBLCR=m | ||
377 | CONFIG_IP_VS_DH=m | ||
378 | CONFIG_IP_VS_SH=m | ||
379 | CONFIG_IP_VS_SED=m | ||
380 | CONFIG_IP_VS_NQ=m | ||
381 | |||
382 | # | ||
383 | # IPVS application helper | ||
384 | # | ||
385 | CONFIG_IP_VS_FTP=m | ||
386 | CONFIG_IPV6=m | 416 | CONFIG_IPV6=m |
387 | CONFIG_IPV6_PRIVACY=y | 417 | CONFIG_IPV6_PRIVACY=y |
388 | CONFIG_IPV6_ROUTER_PREF=y | 418 | CONFIG_IPV6_ROUTER_PREF=y |
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m | |||
399 | CONFIG_INET6_XFRM_MODE_BEET=m | 429 | CONFIG_INET6_XFRM_MODE_BEET=m |
400 | CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m | 430 | CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m |
401 | CONFIG_IPV6_SIT=m | 431 | CONFIG_IPV6_SIT=m |
432 | CONFIG_IPV6_SIT_6RD=y | ||
402 | CONFIG_IPV6_NDISC_NODETYPE=y | 433 | CONFIG_IPV6_NDISC_NODETYPE=y |
403 | CONFIG_IPV6_TUNNEL=m | 434 | CONFIG_IPV6_TUNNEL=m |
404 | CONFIG_IPV6_MULTIPLE_TABLES=y | 435 | CONFIG_IPV6_MULTIPLE_TABLES=y |
405 | CONFIG_IPV6_SUBTREES=y | 436 | CONFIG_IPV6_SUBTREES=y |
406 | # CONFIG_IPV6_MROUTE is not set | 437 | # CONFIG_IPV6_MROUTE is not set |
438 | CONFIG_NETLABEL=y | ||
407 | CONFIG_NETWORK_SECMARK=y | 439 | CONFIG_NETWORK_SECMARK=y |
408 | CONFIG_NETFILTER=y | 440 | CONFIG_NETFILTER=y |
409 | # CONFIG_NETFILTER_DEBUG is not set | 441 | # CONFIG_NETFILTER_DEBUG is not set |
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m | |||
421 | CONFIG_NF_CONNTRACK_SIP=m | 453 | CONFIG_NF_CONNTRACK_SIP=m |
422 | CONFIG_NF_CT_NETLINK=m | 454 | CONFIG_NF_CT_NETLINK=m |
423 | CONFIG_NETFILTER_XTABLES=m | 455 | CONFIG_NETFILTER_XTABLES=m |
456 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | ||
424 | CONFIG_NETFILTER_XT_TARGET_MARK=m | 457 | CONFIG_NETFILTER_XT_TARGET_MARK=m |
425 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m | 458 | CONFIG_NETFILTER_XT_TARGET_NFLOG=m |
426 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m | 459 | CONFIG_NETFILTER_XT_TARGET_SECMARK=m |
427 | CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m | ||
428 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m | 460 | CONFIG_NETFILTER_XT_TARGET_TCPMSS=m |
429 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | 461 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m |
430 | CONFIG_NETFILTER_XT_MATCH_MARK=m | 462 | CONFIG_NETFILTER_XT_MATCH_MARK=m |
431 | CONFIG_NETFILTER_XT_MATCH_POLICY=m | 463 | CONFIG_NETFILTER_XT_MATCH_POLICY=m |
432 | CONFIG_NETFILTER_XT_MATCH_STATE=m | 464 | CONFIG_NETFILTER_XT_MATCH_STATE=m |
465 | CONFIG_IP_VS=m | ||
466 | CONFIG_IP_VS_IPV6=y | ||
467 | # CONFIG_IP_VS_DEBUG is not set | ||
468 | CONFIG_IP_VS_TAB_BITS=12 | ||
469 | |||
470 | # | ||
471 | # IPVS transport protocol load balancing support | ||
472 | # | ||
473 | CONFIG_IP_VS_PROTO_TCP=y | ||
474 | CONFIG_IP_VS_PROTO_UDP=y | ||
475 | CONFIG_IP_VS_PROTO_AH_ESP=y | ||
476 | CONFIG_IP_VS_PROTO_ESP=y | ||
477 | CONFIG_IP_VS_PROTO_AH=y | ||
478 | CONFIG_IP_VS_PROTO_SCTP=y | ||
479 | |||
480 | # | ||
481 | # IPVS scheduler | ||
482 | # | ||
483 | CONFIG_IP_VS_RR=m | ||
484 | CONFIG_IP_VS_WRR=m | ||
485 | CONFIG_IP_VS_LC=m | ||
486 | CONFIG_IP_VS_WLC=m | ||
487 | CONFIG_IP_VS_LBLC=m | ||
488 | CONFIG_IP_VS_LBLCR=m | ||
489 | CONFIG_IP_VS_DH=m | ||
490 | CONFIG_IP_VS_SH=m | ||
491 | CONFIG_IP_VS_SED=m | ||
492 | CONFIG_IP_VS_NQ=m | ||
493 | |||
494 | # | ||
495 | # IPVS application helper | ||
496 | # | ||
497 | CONFIG_IP_VS_FTP=m | ||
433 | 498 | ||
434 | # | 499 | # |
435 | # IP: Netfilter Configuration | 500 | # IP: Netfilter Configuration |
436 | # | 501 | # |
502 | CONFIG_NF_DEFRAG_IPV4=m | ||
437 | CONFIG_NF_CONNTRACK_IPV4=m | 503 | CONFIG_NF_CONNTRACK_IPV4=m |
438 | CONFIG_NF_CONNTRACK_PROC_COMPAT=y | 504 | CONFIG_NF_CONNTRACK_PROC_COMPAT=y |
439 | CONFIG_IP_NF_IPTABLES=m | 505 | CONFIG_IP_NF_IPTABLES=m |
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m | |||
459 | CONFIG_NF_CONNTRACK_IPV6=m | 525 | CONFIG_NF_CONNTRACK_IPV6=m |
460 | CONFIG_IP6_NF_IPTABLES=m | 526 | CONFIG_IP6_NF_IPTABLES=m |
461 | CONFIG_IP6_NF_MATCH_IPV6HEADER=m | 527 | CONFIG_IP6_NF_MATCH_IPV6HEADER=m |
462 | CONFIG_IP6_NF_FILTER=m | ||
463 | CONFIG_IP6_NF_TARGET_LOG=m | 528 | CONFIG_IP6_NF_TARGET_LOG=m |
529 | CONFIG_IP6_NF_FILTER=m | ||
464 | CONFIG_IP6_NF_TARGET_REJECT=m | 530 | CONFIG_IP6_NF_TARGET_REJECT=m |
465 | CONFIG_IP6_NF_MANGLE=m | 531 | CONFIG_IP6_NF_MANGLE=m |
466 | # CONFIG_IP_DCCP is not set | 532 | CONFIG_IP_DCCP=m |
533 | CONFIG_INET_DCCP_DIAG=m | ||
534 | |||
535 | # | ||
536 | # DCCP CCIDs Configuration (EXPERIMENTAL) | ||
537 | # | ||
538 | # CONFIG_IP_DCCP_CCID2_DEBUG is not set | ||
539 | CONFIG_IP_DCCP_CCID3=y | ||
540 | # CONFIG_IP_DCCP_CCID3_DEBUG is not set | ||
541 | CONFIG_IP_DCCP_CCID3_RTO=100 | ||
542 | CONFIG_IP_DCCP_TFRC_LIB=y | ||
543 | |||
544 | # | ||
545 | # DCCP Kernel Hacking | ||
546 | # | ||
547 | # CONFIG_IP_DCCP_DEBUG is not set | ||
467 | CONFIG_IP_SCTP=m | 548 | CONFIG_IP_SCTP=m |
468 | # CONFIG_SCTP_DBG_MSG is not set | 549 | # CONFIG_SCTP_DBG_MSG is not set |
469 | # CONFIG_SCTP_DBG_OBJCNT is not set | 550 | # CONFIG_SCTP_DBG_OBJCNT is not set |
470 | # CONFIG_SCTP_HMAC_NONE is not set | 551 | # CONFIG_SCTP_HMAC_NONE is not set |
471 | # CONFIG_SCTP_HMAC_SHA1 is not set | 552 | CONFIG_SCTP_HMAC_SHA1=y |
472 | CONFIG_SCTP_HMAC_MD5=y | 553 | # CONFIG_SCTP_HMAC_MD5 is not set |
554 | # CONFIG_RDS is not set | ||
473 | # CONFIG_TIPC is not set | 555 | # CONFIG_TIPC is not set |
474 | # CONFIG_ATM is not set | 556 | # CONFIG_ATM is not set |
475 | # CONFIG_BRIDGE is not set | 557 | CONFIG_STP=m |
476 | # CONFIG_VLAN_8021Q is not set | 558 | CONFIG_GARP=m |
559 | CONFIG_BRIDGE=m | ||
560 | CONFIG_BRIDGE_IGMP_SNOOPING=y | ||
561 | # CONFIG_NET_DSA is not set | ||
562 | CONFIG_VLAN_8021Q=m | ||
563 | CONFIG_VLAN_8021Q_GVRP=y | ||
477 | # CONFIG_DECNET is not set | 564 | # CONFIG_DECNET is not set |
565 | CONFIG_LLC=m | ||
478 | # CONFIG_LLC2 is not set | 566 | # CONFIG_LLC2 is not set |
479 | # CONFIG_IPX is not set | 567 | # CONFIG_IPX is not set |
480 | # CONFIG_ATALK is not set | 568 | # CONFIG_ATALK is not set |
@@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y | |||
482 | # CONFIG_LAPB is not set | 570 | # CONFIG_LAPB is not set |
483 | # CONFIG_ECONET is not set | 571 | # CONFIG_ECONET is not set |
484 | # CONFIG_WAN_ROUTER is not set | 572 | # CONFIG_WAN_ROUTER is not set |
573 | # CONFIG_PHONET is not set | ||
574 | # CONFIG_IEEE802154 is not set | ||
485 | # CONFIG_NET_SCHED is not set | 575 | # CONFIG_NET_SCHED is not set |
576 | # CONFIG_DCB is not set | ||
486 | 577 | ||
487 | # | 578 | # |
488 | # Network testing | 579 | # Network testing |
489 | # | 580 | # |
490 | # CONFIG_NET_PKTGEN is not set | 581 | # CONFIG_NET_PKTGEN is not set |
491 | # CONFIG_HAMRADIO is not set | 582 | CONFIG_HAMRADIO=y |
583 | |||
584 | # | ||
585 | # Packet Radio protocols | ||
586 | # | ||
587 | CONFIG_AX25=m | ||
588 | CONFIG_AX25_DAMA_SLAVE=y | ||
589 | CONFIG_NETROM=m | ||
590 | CONFIG_ROSE=m | ||
591 | |||
592 | # | ||
593 | # AX.25 network device drivers | ||
594 | # | ||
595 | CONFIG_MKISS=m | ||
596 | CONFIG_6PACK=m | ||
597 | CONFIG_BPQETHER=m | ||
598 | CONFIG_BAYCOM_SER_FDX=m | ||
599 | CONFIG_BAYCOM_SER_HDX=m | ||
600 | CONFIG_YAM=m | ||
492 | # CONFIG_CAN is not set | 601 | # CONFIG_CAN is not set |
493 | # CONFIG_IRDA is not set | 602 | # CONFIG_IRDA is not set |
494 | # CONFIG_BT is not set | 603 | # CONFIG_BT is not set |
495 | # CONFIG_AF_RXRPC is not set | 604 | # CONFIG_AF_RXRPC is not set |
496 | CONFIG_FIB_RULES=y | 605 | CONFIG_FIB_RULES=y |
606 | CONFIG_WIRELESS=y | ||
607 | # CONFIG_CFG80211 is not set | ||
608 | # CONFIG_LIB80211 is not set | ||
497 | 609 | ||
498 | # | 610 | # |
499 | # Wireless | 611 | # CFG80211 needs to be enabled for MAC80211 |
500 | # | 612 | # |
501 | # CONFIG_CFG80211 is not set | 613 | # CONFIG_WIMAX is not set |
502 | # CONFIG_WIRELESS_EXT is not set | ||
503 | # CONFIG_MAC80211 is not set | ||
504 | # CONFIG_IEEE80211 is not set | ||
505 | # CONFIG_RFKILL is not set | 614 | # CONFIG_RFKILL is not set |
506 | # CONFIG_NET_9P is not set | 615 | # CONFIG_NET_9P is not set |
507 | 616 | ||
@@ -513,9 +622,12 @@ CONFIG_FIB_RULES=y | |||
513 | # Generic Driver Options | 622 | # Generic Driver Options |
514 | # | 623 | # |
515 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 624 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
625 | # CONFIG_DEVTMPFS is not set | ||
516 | CONFIG_STANDALONE=y | 626 | CONFIG_STANDALONE=y |
517 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 627 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
518 | CONFIG_FW_LOADER=m | 628 | CONFIG_FW_LOADER=m |
629 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
630 | CONFIG_EXTRA_FIRMWARE="" | ||
519 | # CONFIG_DEBUG_DRIVER is not set | 631 | # CONFIG_DEBUG_DRIVER is not set |
520 | # CONFIG_DEBUG_DEVRES is not set | 632 | # CONFIG_DEBUG_DEVRES is not set |
521 | # CONFIG_SYS_HYPERVISOR is not set | 633 | # CONFIG_SYS_HYPERVISOR is not set |
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y | |||
530 | # CONFIG_BLK_DEV_COW_COMMON is not set | 642 | # CONFIG_BLK_DEV_COW_COMMON is not set |
531 | CONFIG_BLK_DEV_LOOP=m | 643 | CONFIG_BLK_DEV_LOOP=m |
532 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 644 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
645 | |||
646 | # | ||
647 | # DRBD disabled because PROC_FS, INET or CONNECTOR not selected | ||
648 | # | ||
533 | CONFIG_BLK_DEV_NBD=m | 649 | CONFIG_BLK_DEV_NBD=m |
534 | # CONFIG_BLK_DEV_SX8 is not set | 650 | # CONFIG_BLK_DEV_SX8 is not set |
535 | # CONFIG_BLK_DEV_RAM is not set | 651 | # CONFIG_BLK_DEV_RAM is not set |
536 | # CONFIG_CDROM_PKTCDVD is not set | 652 | # CONFIG_CDROM_PKTCDVD is not set |
537 | # CONFIG_ATA_OVER_ETH is not set | 653 | # CONFIG_ATA_OVER_ETH is not set |
654 | # CONFIG_BLK_DEV_HD is not set | ||
538 | CONFIG_MISC_DEVICES=y | 655 | CONFIG_MISC_DEVICES=y |
656 | # CONFIG_AD525X_DPOT is not set | ||
539 | # CONFIG_PHANTOM is not set | 657 | # CONFIG_PHANTOM is not set |
540 | # CONFIG_EEPROM_93CX6 is not set | ||
541 | CONFIG_SGI_IOC4=m | 658 | CONFIG_SGI_IOC4=m |
542 | # CONFIG_TIFM_CORE is not set | 659 | # CONFIG_TIFM_CORE is not set |
660 | # CONFIG_ICS932S401 is not set | ||
543 | # CONFIG_ENCLOSURE_SERVICES is not set | 661 | # CONFIG_ENCLOSURE_SERVICES is not set |
662 | # CONFIG_HP_ILO is not set | ||
663 | # CONFIG_ISL29003 is not set | ||
664 | # CONFIG_SENSORS_TSL2550 is not set | ||
665 | # CONFIG_DS1682 is not set | ||
666 | # CONFIG_C2PORT is not set | ||
667 | |||
668 | # | ||
669 | # EEPROM support | ||
670 | # | ||
671 | # CONFIG_EEPROM_AT24 is not set | ||
672 | CONFIG_EEPROM_LEGACY=y | ||
673 | CONFIG_EEPROM_MAX6875=y | ||
674 | # CONFIG_EEPROM_93CX6 is not set | ||
675 | # CONFIG_CB710_CORE is not set | ||
544 | CONFIG_HAVE_IDE=y | 676 | CONFIG_HAVE_IDE=y |
545 | CONFIG_IDE=y | 677 | CONFIG_IDE=y |
546 | CONFIG_IDE_MAX_HWIFS=4 | ||
547 | CONFIG_BLK_DEV_IDE=y | ||
548 | 678 | ||
549 | # | 679 | # |
550 | # Please see Documentation/ide/ide.txt for help/info on IDE drives | 680 | # Please see Documentation/ide/ide.txt for help/info on IDE drives |
551 | # | 681 | # |
682 | CONFIG_IDE_XFER_MODE=y | ||
683 | CONFIG_IDE_TIMINGS=y | ||
684 | CONFIG_IDE_ATAPI=y | ||
552 | # CONFIG_BLK_DEV_IDE_SATA is not set | 685 | # CONFIG_BLK_DEV_IDE_SATA is not set |
553 | CONFIG_BLK_DEV_IDEDISK=y | 686 | CONFIG_IDE_GD=y |
554 | # CONFIG_IDEDISK_MULTI_MODE is not set | 687 | CONFIG_IDE_GD_ATA=y |
688 | # CONFIG_IDE_GD_ATAPI is not set | ||
555 | CONFIG_BLK_DEV_IDECD=y | 689 | CONFIG_BLK_DEV_IDECD=y |
556 | CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y | 690 | CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y |
557 | CONFIG_BLK_DEV_IDETAPE=y | 691 | CONFIG_BLK_DEV_IDETAPE=y |
558 | CONFIG_BLK_DEV_IDEFLOPPY=y | ||
559 | # CONFIG_BLK_DEV_IDESCSI is not set | ||
560 | # CONFIG_IDE_TASK_IOCTL is not set | 692 | # CONFIG_IDE_TASK_IOCTL is not set |
561 | CONFIG_IDE_PROC_FS=y | 693 | CONFIG_IDE_PROC_FS=y |
562 | 694 | ||
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y | |||
581 | # CONFIG_BLK_DEV_AMD74XX is not set | 713 | # CONFIG_BLK_DEV_AMD74XX is not set |
582 | CONFIG_BLK_DEV_CMD64X=y | 714 | CONFIG_BLK_DEV_CMD64X=y |
583 | # CONFIG_BLK_DEV_TRIFLEX is not set | 715 | # CONFIG_BLK_DEV_TRIFLEX is not set |
584 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
585 | # CONFIG_BLK_DEV_CS5520 is not set | 716 | # CONFIG_BLK_DEV_CS5520 is not set |
586 | # CONFIG_BLK_DEV_CS5530 is not set | 717 | # CONFIG_BLK_DEV_CS5530 is not set |
587 | # CONFIG_BLK_DEV_HPT34X is not set | ||
588 | # CONFIG_BLK_DEV_HPT366 is not set | 718 | # CONFIG_BLK_DEV_HPT366 is not set |
589 | # CONFIG_BLK_DEV_JMICRON is not set | 719 | # CONFIG_BLK_DEV_JMICRON is not set |
590 | # CONFIG_BLK_DEV_SC1200 is not set | 720 | # CONFIG_BLK_DEV_SC1200 is not set |
591 | # CONFIG_BLK_DEV_PIIX is not set | 721 | # CONFIG_BLK_DEV_PIIX is not set |
722 | # CONFIG_BLK_DEV_IT8172 is not set | ||
592 | CONFIG_BLK_DEV_IT8213=m | 723 | CONFIG_BLK_DEV_IT8213=m |
593 | # CONFIG_BLK_DEV_IT821X is not set | 724 | # CONFIG_BLK_DEV_IT821X is not set |
594 | # CONFIG_BLK_DEV_NS87415 is not set | 725 | # CONFIG_BLK_DEV_NS87415 is not set |
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m | |||
600 | # CONFIG_BLK_DEV_TRM290 is not set | 731 | # CONFIG_BLK_DEV_TRM290 is not set |
601 | # CONFIG_BLK_DEV_VIA82CXXX is not set | 732 | # CONFIG_BLK_DEV_VIA82CXXX is not set |
602 | CONFIG_BLK_DEV_TC86C001=m | 733 | CONFIG_BLK_DEV_TC86C001=m |
603 | # CONFIG_BLK_DEV_IDE_SWARM is not set | ||
604 | CONFIG_BLK_DEV_IDEDMA=y | 734 | CONFIG_BLK_DEV_IDEDMA=y |
605 | # CONFIG_BLK_DEV_HD_ONLY is not set | ||
606 | # CONFIG_BLK_DEV_HD is not set | ||
607 | 735 | ||
608 | # | 736 | # |
609 | # SCSI device support | 737 | # SCSI device support |
610 | # | 738 | # |
739 | CONFIG_SCSI_MOD=y | ||
611 | # CONFIG_RAID_ATTRS is not set | 740 | # CONFIG_RAID_ATTRS is not set |
612 | CONFIG_SCSI=y | 741 | CONFIG_SCSI=y |
613 | CONFIG_SCSI_DMA=y | 742 | CONFIG_SCSI_DMA=y |
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m | |||
625 | CONFIG_BLK_DEV_SR_VENDOR=y | 754 | CONFIG_BLK_DEV_SR_VENDOR=y |
626 | CONFIG_CHR_DEV_SG=m | 755 | CONFIG_CHR_DEV_SG=m |
627 | CONFIG_CHR_DEV_SCH=m | 756 | CONFIG_CHR_DEV_SCH=m |
628 | |||
629 | # | ||
630 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
631 | # | ||
632 | # CONFIG_SCSI_MULTI_LUN is not set | 757 | # CONFIG_SCSI_MULTI_LUN is not set |
633 | # CONFIG_SCSI_CONSTANTS is not set | 758 | # CONFIG_SCSI_CONSTANTS is not set |
634 | # CONFIG_SCSI_LOGGING is not set | 759 | # CONFIG_SCSI_LOGGING is not set |
@@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m | |||
645 | # CONFIG_SCSI_SRP_ATTRS is not set | 770 | # CONFIG_SCSI_SRP_ATTRS is not set |
646 | CONFIG_SCSI_LOWLEVEL=y | 771 | CONFIG_SCSI_LOWLEVEL=y |
647 | # CONFIG_ISCSI_TCP is not set | 772 | # CONFIG_ISCSI_TCP is not set |
773 | # CONFIG_SCSI_CXGB3_ISCSI is not set | ||
774 | # CONFIG_SCSI_BNX2_ISCSI is not set | ||
775 | # CONFIG_BE2ISCSI is not set | ||
648 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 776 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
777 | # CONFIG_SCSI_HPSA is not set | ||
649 | # CONFIG_SCSI_3W_9XXX is not set | 778 | # CONFIG_SCSI_3W_9XXX is not set |
779 | # CONFIG_SCSI_3W_SAS is not set | ||
650 | # CONFIG_SCSI_ACARD is not set | 780 | # CONFIG_SCSI_ACARD is not set |
651 | # CONFIG_SCSI_AACRAID is not set | 781 | # CONFIG_SCSI_AACRAID is not set |
652 | # CONFIG_SCSI_AIC7XXX is not set | 782 | # CONFIG_SCSI_AIC7XXX is not set |
653 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 783 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
654 | # CONFIG_SCSI_AIC79XX is not set | 784 | # CONFIG_SCSI_AIC79XX is not set |
655 | # CONFIG_SCSI_AIC94XX is not set | 785 | # CONFIG_SCSI_AIC94XX is not set |
786 | # CONFIG_SCSI_MVSAS is not set | ||
656 | # CONFIG_SCSI_DPT_I2O is not set | 787 | # CONFIG_SCSI_DPT_I2O is not set |
657 | # CONFIG_SCSI_ADVANSYS is not set | 788 | # CONFIG_SCSI_ADVANSYS is not set |
658 | # CONFIG_SCSI_ARCMSR is not set | 789 | # CONFIG_SCSI_ARCMSR is not set |
659 | # CONFIG_MEGARAID_NEWGEN is not set | 790 | # CONFIG_MEGARAID_NEWGEN is not set |
660 | # CONFIG_MEGARAID_LEGACY is not set | 791 | # CONFIG_MEGARAID_LEGACY is not set |
661 | # CONFIG_MEGARAID_SAS is not set | 792 | # CONFIG_MEGARAID_SAS is not set |
793 | # CONFIG_SCSI_MPT2SAS is not set | ||
662 | # CONFIG_SCSI_HPTIOP is not set | 794 | # CONFIG_SCSI_HPTIOP is not set |
795 | # CONFIG_LIBFC is not set | ||
796 | # CONFIG_LIBFCOE is not set | ||
797 | # CONFIG_FCOE is not set | ||
663 | # CONFIG_SCSI_DMX3191D is not set | 798 | # CONFIG_SCSI_DMX3191D is not set |
664 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 799 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
665 | # CONFIG_SCSI_IPS is not set | 800 | # CONFIG_SCSI_IPS is not set |
666 | # CONFIG_SCSI_INITIO is not set | 801 | # CONFIG_SCSI_INITIO is not set |
667 | # CONFIG_SCSI_INIA100 is not set | 802 | # CONFIG_SCSI_INIA100 is not set |
668 | # CONFIG_SCSI_MVSAS is not set | ||
669 | # CONFIG_SCSI_STEX is not set | 803 | # CONFIG_SCSI_STEX is not set |
670 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 804 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
671 | # CONFIG_SCSI_IPR is not set | 805 | # CONFIG_SCSI_IPR is not set |
@@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y | |||
676 | # CONFIG_SCSI_DC395x is not set | 810 | # CONFIG_SCSI_DC395x is not set |
677 | # CONFIG_SCSI_DC390T is not set | 811 | # CONFIG_SCSI_DC390T is not set |
678 | # CONFIG_SCSI_DEBUG is not set | 812 | # CONFIG_SCSI_DEBUG is not set |
813 | # CONFIG_SCSI_PMCRAID is not set | ||
814 | # CONFIG_SCSI_PM8001 is not set | ||
679 | # CONFIG_SCSI_SRP is not set | 815 | # CONFIG_SCSI_SRP is not set |
816 | # CONFIG_SCSI_BFA_FC is not set | ||
817 | # CONFIG_SCSI_DH is not set | ||
818 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
680 | CONFIG_ATA=y | 819 | CONFIG_ATA=y |
681 | # CONFIG_ATA_NONSTANDARD is not set | 820 | # CONFIG_ATA_NONSTANDARD is not set |
821 | CONFIG_ATA_VERBOSE_ERROR=y | ||
682 | CONFIG_SATA_PMP=y | 822 | CONFIG_SATA_PMP=y |
683 | # CONFIG_SATA_AHCI is not set | 823 | # CONFIG_SATA_AHCI is not set |
684 | CONFIG_SATA_SIL24=y | 824 | CONFIG_SATA_SIL24=y |
@@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y | |||
700 | # CONFIG_PATA_ALI is not set | 840 | # CONFIG_PATA_ALI is not set |
701 | # CONFIG_PATA_AMD is not set | 841 | # CONFIG_PATA_AMD is not set |
702 | # CONFIG_PATA_ARTOP is not set | 842 | # CONFIG_PATA_ARTOP is not set |
843 | # CONFIG_PATA_ATP867X is not set | ||
703 | # CONFIG_PATA_ATIIXP is not set | 844 | # CONFIG_PATA_ATIIXP is not set |
704 | # CONFIG_PATA_CMD640_PCI is not set | 845 | # CONFIG_PATA_CMD640_PCI is not set |
705 | # CONFIG_PATA_CMD64X is not set | 846 | # CONFIG_PATA_CMD64X is not set |
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y | |||
715 | # CONFIG_PATA_IT821X is not set | 856 | # CONFIG_PATA_IT821X is not set |
716 | # CONFIG_PATA_IT8213 is not set | 857 | # CONFIG_PATA_IT8213 is not set |
717 | # CONFIG_PATA_JMICRON is not set | 858 | # CONFIG_PATA_JMICRON is not set |
859 | # CONFIG_PATA_LEGACY is not set | ||
718 | # CONFIG_PATA_TRIFLEX is not set | 860 | # CONFIG_PATA_TRIFLEX is not set |
719 | # CONFIG_PATA_MARVELL is not set | 861 | # CONFIG_PATA_MARVELL is not set |
720 | # CONFIG_PATA_MPIIX is not set | 862 | # CONFIG_PATA_MPIIX is not set |
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y | |||
725 | # CONFIG_PATA_NS87415 is not set | 867 | # CONFIG_PATA_NS87415 is not set |
726 | # CONFIG_PATA_OPTI is not set | 868 | # CONFIG_PATA_OPTI is not set |
727 | # CONFIG_PATA_OPTIDMA is not set | 869 | # CONFIG_PATA_OPTIDMA is not set |
870 | # CONFIG_PATA_PDC2027X is not set | ||
728 | # CONFIG_PATA_PDC_OLD is not set | 871 | # CONFIG_PATA_PDC_OLD is not set |
729 | # CONFIG_PATA_RADISYS is not set | 872 | # CONFIG_PATA_RADISYS is not set |
873 | # CONFIG_PATA_RDC is not set | ||
730 | # CONFIG_PATA_RZ1000 is not set | 874 | # CONFIG_PATA_RZ1000 is not set |
731 | # CONFIG_PATA_SC1200 is not set | 875 | # CONFIG_PATA_SC1200 is not set |
732 | # CONFIG_PATA_SERVERWORKS is not set | 876 | # CONFIG_PATA_SERVERWORKS is not set |
733 | # CONFIG_PATA_PDC2027X is not set | ||
734 | CONFIG_PATA_SIL680=y | 877 | CONFIG_PATA_SIL680=y |
735 | # CONFIG_PATA_SIS is not set | 878 | # CONFIG_PATA_SIS is not set |
879 | # CONFIG_PATA_TOSHIBA is not set | ||
736 | # CONFIG_PATA_VIA is not set | 880 | # CONFIG_PATA_VIA is not set |
737 | # CONFIG_PATA_WINBOND is not set | 881 | # CONFIG_PATA_WINBOND is not set |
738 | # CONFIG_PATA_PLATFORM is not set | 882 | # CONFIG_PATA_PLATFORM is not set |
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y | |||
745 | # | 889 | # |
746 | 890 | ||
747 | # | 891 | # |
748 | # Enable only one of the two stacks, unless you know what you are doing | 892 | # You can enable one or both FireWire driver stacks. |
893 | # | ||
894 | |||
895 | # | ||
896 | # The newer stack is recommended. | ||
749 | # | 897 | # |
750 | # CONFIG_FIREWIRE is not set | 898 | # CONFIG_FIREWIRE is not set |
751 | # CONFIG_IEEE1394 is not set | 899 | # CONFIG_IEEE1394 is not set |
752 | # CONFIG_I2O is not set | 900 | # CONFIG_I2O is not set |
753 | CONFIG_NETDEVICES=y | 901 | CONFIG_NETDEVICES=y |
754 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
755 | # CONFIG_DUMMY is not set | 902 | # CONFIG_DUMMY is not set |
756 | # CONFIG_BONDING is not set | 903 | # CONFIG_BONDING is not set |
757 | # CONFIG_MACVLAN is not set | 904 | # CONFIG_MACVLAN is not set |
@@ -774,6 +921,9 @@ CONFIG_PHYLIB=y | |||
774 | # CONFIG_BROADCOM_PHY is not set | 921 | # CONFIG_BROADCOM_PHY is not set |
775 | # CONFIG_ICPLUS_PHY is not set | 922 | # CONFIG_ICPLUS_PHY is not set |
776 | # CONFIG_REALTEK_PHY is not set | 923 | # CONFIG_REALTEK_PHY is not set |
924 | # CONFIG_NATIONAL_PHY is not set | ||
925 | # CONFIG_STE10XP is not set | ||
926 | # CONFIG_LSI_ET1011C_PHY is not set | ||
777 | # CONFIG_FIXED_PHY is not set | 927 | # CONFIG_FIXED_PHY is not set |
778 | # CONFIG_MDIO_BITBANG is not set | 928 | # CONFIG_MDIO_BITBANG is not set |
779 | CONFIG_NET_ETHERNET=y | 929 | CONFIG_NET_ETHERNET=y |
@@ -783,23 +933,33 @@ CONFIG_MII=y | |||
783 | # CONFIG_SUNGEM is not set | 933 | # CONFIG_SUNGEM is not set |
784 | # CONFIG_CASSINI is not set | 934 | # CONFIG_CASSINI is not set |
785 | # CONFIG_NET_VENDOR_3COM is not set | 935 | # CONFIG_NET_VENDOR_3COM is not set |
936 | # CONFIG_SMC91X is not set | ||
786 | # CONFIG_DM9000 is not set | 937 | # CONFIG_DM9000 is not set |
938 | # CONFIG_ETHOC is not set | ||
939 | # CONFIG_SMSC911X is not set | ||
940 | # CONFIG_DNET is not set | ||
787 | # CONFIG_NET_TULIP is not set | 941 | # CONFIG_NET_TULIP is not set |
788 | # CONFIG_HP100 is not set | 942 | # CONFIG_HP100 is not set |
789 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | 943 | # CONFIG_IBM_NEW_EMAC_ZMII is not set |
790 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | 944 | # CONFIG_IBM_NEW_EMAC_RGMII is not set |
791 | # CONFIG_IBM_NEW_EMAC_TAH is not set | 945 | # CONFIG_IBM_NEW_EMAC_TAH is not set |
792 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | 946 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set |
947 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
948 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
949 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
793 | # CONFIG_NET_PCI is not set | 950 | # CONFIG_NET_PCI is not set |
794 | # CONFIG_B44 is not set | 951 | # CONFIG_B44 is not set |
952 | # CONFIG_KS8842 is not set | ||
953 | # CONFIG_KS8851_MLL is not set | ||
954 | # CONFIG_ATL2 is not set | ||
795 | CONFIG_NETDEV_1000=y | 955 | CONFIG_NETDEV_1000=y |
796 | # CONFIG_ACENIC is not set | 956 | # CONFIG_ACENIC is not set |
797 | # CONFIG_DL2K is not set | 957 | # CONFIG_DL2K is not set |
798 | # CONFIG_E1000 is not set | 958 | # CONFIG_E1000 is not set |
799 | # CONFIG_E1000E is not set | 959 | # CONFIG_E1000E is not set |
800 | # CONFIG_E1000E_ENABLED is not set | ||
801 | # CONFIG_IP1000 is not set | 960 | # CONFIG_IP1000 is not set |
802 | # CONFIG_IGB is not set | 961 | # CONFIG_IGB is not set |
962 | # CONFIG_IGBVF is not set | ||
803 | # CONFIG_NS83820 is not set | 963 | # CONFIG_NS83820 is not set |
804 | # CONFIG_HAMACHI is not set | 964 | # CONFIG_HAMACHI is not set |
805 | # CONFIG_YELLOWFIN is not set | 965 | # CONFIG_YELLOWFIN is not set |
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y | |||
811 | # CONFIG_VIA_VELOCITY is not set | 971 | # CONFIG_VIA_VELOCITY is not set |
812 | # CONFIG_TIGON3 is not set | 972 | # CONFIG_TIGON3 is not set |
813 | # CONFIG_BNX2 is not set | 973 | # CONFIG_BNX2 is not set |
974 | # CONFIG_CNIC is not set | ||
814 | # CONFIG_QLA3XXX is not set | 975 | # CONFIG_QLA3XXX is not set |
815 | # CONFIG_ATL1 is not set | 976 | # CONFIG_ATL1 is not set |
977 | # CONFIG_ATL1E is not set | ||
978 | # CONFIG_ATL1C is not set | ||
979 | # CONFIG_JME is not set | ||
816 | CONFIG_NETDEV_10000=y | 980 | CONFIG_NETDEV_10000=y |
981 | CONFIG_MDIO=m | ||
817 | # CONFIG_CHELSIO_T1 is not set | 982 | # CONFIG_CHELSIO_T1 is not set |
983 | CONFIG_CHELSIO_T3_DEPENDS=y | ||
818 | CONFIG_CHELSIO_T3=m | 984 | CONFIG_CHELSIO_T3=m |
985 | # CONFIG_ENIC is not set | ||
819 | # CONFIG_IXGBE is not set | 986 | # CONFIG_IXGBE is not set |
820 | # CONFIG_IXGB is not set | 987 | # CONFIG_IXGB is not set |
821 | # CONFIG_S2IO is not set | 988 | # CONFIG_S2IO is not set |
989 | # CONFIG_VXGE is not set | ||
822 | # CONFIG_MYRI10GE is not set | 990 | # CONFIG_MYRI10GE is not set |
823 | CONFIG_NETXEN_NIC=m | 991 | CONFIG_NETXEN_NIC=m |
824 | # CONFIG_NIU is not set | 992 | # CONFIG_NIU is not set |
993 | # CONFIG_MLX4_EN is not set | ||
825 | # CONFIG_MLX4_CORE is not set | 994 | # CONFIG_MLX4_CORE is not set |
826 | # CONFIG_TEHUTI is not set | 995 | # CONFIG_TEHUTI is not set |
827 | # CONFIG_BNX2X is not set | 996 | # CONFIG_BNX2X is not set |
997 | # CONFIG_QLCNIC is not set | ||
998 | # CONFIG_QLGE is not set | ||
828 | # CONFIG_SFC is not set | 999 | # CONFIG_SFC is not set |
1000 | # CONFIG_BE2NET is not set | ||
829 | # CONFIG_TR is not set | 1001 | # CONFIG_TR is not set |
1002 | CONFIG_WLAN=y | ||
1003 | # CONFIG_ATMEL is not set | ||
1004 | # CONFIG_PRISM54 is not set | ||
1005 | # CONFIG_HOSTAP is not set | ||
830 | 1006 | ||
831 | # | 1007 | # |
832 | # Wireless LAN | 1008 | # Enable WiMAX (Networking options) to see the WiMAX drivers |
833 | # | 1009 | # |
834 | # CONFIG_WLAN_PRE80211 is not set | ||
835 | # CONFIG_WLAN_80211 is not set | ||
836 | # CONFIG_IWLWIFI_LEDS is not set | ||
837 | # CONFIG_WAN is not set | 1010 | # CONFIG_WAN is not set |
838 | # CONFIG_FDDI is not set | 1011 | # CONFIG_FDDI is not set |
839 | # CONFIG_HIPPI is not set | 1012 | # CONFIG_HIPPI is not set |
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y | |||
856 | # CONFIG_NETCONSOLE is not set | 1029 | # CONFIG_NETCONSOLE is not set |
857 | # CONFIG_NETPOLL is not set | 1030 | # CONFIG_NETPOLL is not set |
858 | # CONFIG_NET_POLL_CONTROLLER is not set | 1031 | # CONFIG_NET_POLL_CONTROLLER is not set |
1032 | # CONFIG_VMXNET3 is not set | ||
859 | # CONFIG_ISDN is not set | 1033 | # CONFIG_ISDN is not set |
860 | # CONFIG_PHONE is not set | 1034 | # CONFIG_PHONE is not set |
861 | 1035 | ||
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y | |||
873 | # CONFIG_SERIO_PCIPS2 is not set | 1047 | # CONFIG_SERIO_PCIPS2 is not set |
874 | # CONFIG_SERIO_LIBPS2 is not set | 1048 | # CONFIG_SERIO_LIBPS2 is not set |
875 | CONFIG_SERIO_RAW=m | 1049 | CONFIG_SERIO_RAW=m |
1050 | # CONFIG_SERIO_ALTERA_PS2 is not set | ||
876 | # CONFIG_GAMEPORT is not set | 1051 | # CONFIG_GAMEPORT is not set |
877 | 1052 | ||
878 | # | 1053 | # |
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y | |||
893 | # CONFIG_N_HDLC is not set | 1068 | # CONFIG_N_HDLC is not set |
894 | # CONFIG_RISCOM8 is not set | 1069 | # CONFIG_RISCOM8 is not set |
895 | # CONFIG_SPECIALIX is not set | 1070 | # CONFIG_SPECIALIX is not set |
896 | # CONFIG_SX is not set | ||
897 | # CONFIG_RIO is not set | ||
898 | # CONFIG_STALDRV is not set | 1071 | # CONFIG_STALDRV is not set |
899 | # CONFIG_NOZOMI is not set | 1072 | # CONFIG_NOZOMI is not set |
900 | 1073 | ||
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y | |||
911 | CONFIG_SERIAL_CORE=y | 1084 | CONFIG_SERIAL_CORE=y |
912 | CONFIG_SERIAL_CORE_CONSOLE=y | 1085 | CONFIG_SERIAL_CORE_CONSOLE=y |
913 | # CONFIG_SERIAL_JSM is not set | 1086 | # CONFIG_SERIAL_JSM is not set |
1087 | # CONFIG_SERIAL_TIMBERDALE is not set | ||
914 | CONFIG_UNIX98_PTYS=y | 1088 | CONFIG_UNIX98_PTYS=y |
1089 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
915 | CONFIG_LEGACY_PTYS=y | 1090 | CONFIG_LEGACY_PTYS=y |
916 | CONFIG_LEGACY_PTY_COUNT=256 | 1091 | CONFIG_LEGACY_PTY_COUNT=256 |
917 | # CONFIG_IPMI_HANDLER is not set | 1092 | # CONFIG_IPMI_HANDLER is not set |
@@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
923 | CONFIG_DEVPORT=y | 1098 | CONFIG_DEVPORT=y |
924 | CONFIG_I2C=y | 1099 | CONFIG_I2C=y |
925 | CONFIG_I2C_BOARDINFO=y | 1100 | CONFIG_I2C_BOARDINFO=y |
1101 | CONFIG_I2C_COMPAT=y | ||
926 | CONFIG_I2C_CHARDEV=y | 1102 | CONFIG_I2C_CHARDEV=y |
1103 | CONFIG_I2C_HELPER_AUTO=y | ||
927 | 1104 | ||
928 | # | 1105 | # |
929 | # I2C Hardware Bus support | 1106 | # I2C Hardware Bus support |
930 | # | 1107 | # |
1108 | |||
1109 | # | ||
1110 | # PC SMBus host controller drivers | ||
1111 | # | ||
931 | # CONFIG_I2C_ALI1535 is not set | 1112 | # CONFIG_I2C_ALI1535 is not set |
932 | # CONFIG_I2C_ALI1563 is not set | 1113 | # CONFIG_I2C_ALI1563 is not set |
933 | # CONFIG_I2C_ALI15X3 is not set | 1114 | # CONFIG_I2C_ALI15X3 is not set |
934 | # CONFIG_I2C_AMD756 is not set | 1115 | # CONFIG_I2C_AMD756 is not set |
935 | # CONFIG_I2C_AMD8111 is not set | 1116 | # CONFIG_I2C_AMD8111 is not set |
936 | # CONFIG_I2C_I801 is not set | 1117 | # CONFIG_I2C_I801 is not set |
937 | # CONFIG_I2C_I810 is not set | 1118 | # CONFIG_I2C_ISCH is not set |
938 | # CONFIG_I2C_PIIX4 is not set | 1119 | # CONFIG_I2C_PIIX4 is not set |
939 | # CONFIG_I2C_NFORCE2 is not set | 1120 | # CONFIG_I2C_NFORCE2 is not set |
940 | # CONFIG_I2C_OCORES is not set | ||
941 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
942 | # CONFIG_I2C_PROSAVAGE is not set | ||
943 | # CONFIG_I2C_SAVAGE4 is not set | ||
944 | CONFIG_I2C_SIBYTE=y | ||
945 | # CONFIG_I2C_SIMTEC is not set | ||
946 | # CONFIG_I2C_SIS5595 is not set | 1121 | # CONFIG_I2C_SIS5595 is not set |
947 | # CONFIG_I2C_SIS630 is not set | 1122 | # CONFIG_I2C_SIS630 is not set |
948 | # CONFIG_I2C_SIS96X is not set | 1123 | # CONFIG_I2C_SIS96X is not set |
949 | # CONFIG_I2C_TAOS_EVM is not set | ||
950 | # CONFIG_I2C_STUB is not set | ||
951 | # CONFIG_I2C_VIA is not set | 1124 | # CONFIG_I2C_VIA is not set |
952 | # CONFIG_I2C_VIAPRO is not set | 1125 | # CONFIG_I2C_VIAPRO is not set |
953 | # CONFIG_I2C_VOODOO3 is not set | ||
954 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
955 | 1126 | ||
956 | # | 1127 | # |
957 | # Miscellaneous I2C Chip support | 1128 | # I2C system bus drivers (mostly embedded / system-on-chip) |
958 | # | 1129 | # |
959 | # CONFIG_DS1682 is not set | 1130 | # CONFIG_I2C_OCORES is not set |
960 | CONFIG_EEPROM_LEGACY=y | 1131 | # CONFIG_I2C_SIMTEC is not set |
961 | CONFIG_SENSORS_PCF8574=y | 1132 | # CONFIG_I2C_XILINX is not set |
962 | # CONFIG_PCF8575 is not set | 1133 | |
963 | CONFIG_SENSORS_PCF8591=y | 1134 | # |
964 | CONFIG_EEPROM_MAX6875=y | 1135 | # External I2C/SMBus adapter drivers |
965 | # CONFIG_SENSORS_TSL2550 is not set | 1136 | # |
1137 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
1138 | # CONFIG_I2C_TAOS_EVM is not set | ||
1139 | |||
1140 | # | ||
1141 | # Other I2C/SMBus bus drivers | ||
1142 | # | ||
1143 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
1144 | CONFIG_I2C_SIBYTE=y | ||
1145 | # CONFIG_I2C_STUB is not set | ||
966 | CONFIG_I2C_DEBUG_CORE=y | 1146 | CONFIG_I2C_DEBUG_CORE=y |
967 | CONFIG_I2C_DEBUG_ALGO=y | 1147 | CONFIG_I2C_DEBUG_ALGO=y |
968 | CONFIG_I2C_DEBUG_BUS=y | 1148 | CONFIG_I2C_DEBUG_BUS=y |
969 | CONFIG_I2C_DEBUG_CHIP=y | ||
970 | # CONFIG_SPI is not set | 1149 | # CONFIG_SPI is not set |
1150 | |||
1151 | # | ||
1152 | # PPS support | ||
1153 | # | ||
1154 | # CONFIG_PPS is not set | ||
971 | # CONFIG_W1 is not set | 1155 | # CONFIG_W1 is not set |
972 | # CONFIG_POWER_SUPPLY is not set | 1156 | # CONFIG_POWER_SUPPLY is not set |
973 | # CONFIG_HWMON is not set | 1157 | # CONFIG_HWMON is not set |
974 | # CONFIG_THERMAL is not set | 1158 | # CONFIG_THERMAL is not set |
975 | # CONFIG_THERMAL_HWMON is not set | ||
976 | # CONFIG_WATCHDOG is not set | 1159 | # CONFIG_WATCHDOG is not set |
1160 | CONFIG_SSB_POSSIBLE=y | ||
977 | 1161 | ||
978 | # | 1162 | # |
979 | # Sonics Silicon Backplane | 1163 | # Sonics Silicon Backplane |
980 | # | 1164 | # |
981 | CONFIG_SSB_POSSIBLE=y | ||
982 | # CONFIG_SSB is not set | 1165 | # CONFIG_SSB is not set |
983 | 1166 | ||
984 | # | 1167 | # |
985 | # Multifunction device drivers | 1168 | # Multifunction device drivers |
986 | # | 1169 | # |
1170 | # CONFIG_MFD_CORE is not set | ||
1171 | # CONFIG_MFD_88PM860X is not set | ||
987 | # CONFIG_MFD_SM501 is not set | 1172 | # CONFIG_MFD_SM501 is not set |
988 | # CONFIG_HTC_PASIC3 is not set | 1173 | # CONFIG_HTC_PASIC3 is not set |
989 | 1174 | # CONFIG_TWL4030_CORE is not set | |
990 | # | 1175 | # CONFIG_MFD_TMIO is not set |
991 | # Multimedia devices | 1176 | # CONFIG_PMIC_DA903X is not set |
992 | # | 1177 | # CONFIG_PMIC_ADP5520 is not set |
993 | 1178 | # CONFIG_MFD_MAX8925 is not set | |
994 | # | 1179 | # CONFIG_MFD_WM8400 is not set |
995 | # Multimedia core support | 1180 | # CONFIG_MFD_WM831X is not set |
996 | # | 1181 | # CONFIG_MFD_WM8350_I2C is not set |
997 | # CONFIG_VIDEO_DEV is not set | 1182 | # CONFIG_MFD_WM8994 is not set |
998 | # CONFIG_DVB_CORE is not set | 1183 | # CONFIG_MFD_PCF50633 is not set |
999 | # CONFIG_VIDEO_MEDIA is not set | 1184 | # CONFIG_AB3100_CORE is not set |
1000 | 1185 | # CONFIG_LPC_SCH is not set | |
1001 | # | 1186 | # CONFIG_REGULATOR is not set |
1002 | # Multimedia drivers | 1187 | # CONFIG_MEDIA_SUPPORT is not set |
1003 | # | ||
1004 | # CONFIG_DAB is not set | ||
1005 | 1188 | ||
1006 | # | 1189 | # |
1007 | # Graphics support | 1190 | # Graphics support |
1008 | # | 1191 | # |
1192 | CONFIG_VGA_ARB=y | ||
1193 | CONFIG_VGA_ARB_MAX_GPUS=16 | ||
1009 | # CONFIG_DRM is not set | 1194 | # CONFIG_DRM is not set |
1010 | # CONFIG_VGASTATE is not set | 1195 | # CONFIG_VGASTATE is not set |
1011 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | 1196 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set |
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y | |||
1016 | # Display device support | 1201 | # Display device support |
1017 | # | 1202 | # |
1018 | # CONFIG_DISPLAY_SUPPORT is not set | 1203 | # CONFIG_DISPLAY_SUPPORT is not set |
1019 | |||
1020 | # | ||
1021 | # Sound | ||
1022 | # | ||
1023 | # CONFIG_SOUND is not set | 1204 | # CONFIG_SOUND is not set |
1024 | CONFIG_USB_SUPPORT=y | 1205 | CONFIG_USB_SUPPORT=y |
1025 | CONFIG_USB_ARCH_HAS_HCD=y | 1206 | CONFIG_USB_ARCH_HAS_HCD=y |
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
1030 | # CONFIG_USB_OTG_BLACKLIST_HUB is not set | 1211 | # CONFIG_USB_OTG_BLACKLIST_HUB is not set |
1031 | 1212 | ||
1032 | # | 1213 | # |
1033 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | 1214 | # Enable Host or Gadget support to see Inventra options |
1215 | # | ||
1216 | |||
1217 | # | ||
1218 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
1034 | # | 1219 | # |
1035 | # CONFIG_USB_GADGET is not set | 1220 | # CONFIG_USB_GADGET is not set |
1221 | |||
1222 | # | ||
1223 | # OTG and related infrastructure | ||
1224 | # | ||
1225 | # CONFIG_UWB is not set | ||
1036 | # CONFIG_MMC is not set | 1226 | # CONFIG_MMC is not set |
1037 | # CONFIG_MEMSTICK is not set | 1227 | # CONFIG_MEMSTICK is not set |
1038 | # CONFIG_NEW_LEDS is not set | 1228 | # CONFIG_NEW_LEDS is not set |
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y | |||
1040 | # CONFIG_INFINIBAND is not set | 1230 | # CONFIG_INFINIBAND is not set |
1041 | CONFIG_RTC_LIB=y | 1231 | CONFIG_RTC_LIB=y |
1042 | # CONFIG_RTC_CLASS is not set | 1232 | # CONFIG_RTC_CLASS is not set |
1233 | # CONFIG_DMADEVICES is not set | ||
1234 | # CONFIG_AUXDISPLAY is not set | ||
1043 | # CONFIG_UIO is not set | 1235 | # CONFIG_UIO is not set |
1044 | 1236 | ||
1045 | # | 1237 | # |
1238 | # TI VLYNQ | ||
1239 | # | ||
1240 | # CONFIG_STAGING is not set | ||
1241 | |||
1242 | # | ||
1046 | # File systems | 1243 | # File systems |
1047 | # | 1244 | # |
1048 | CONFIG_EXT2_FS=m | 1245 | CONFIG_EXT2_FS=m |
1049 | CONFIG_EXT2_FS_XATTR=y | 1246 | CONFIG_EXT2_FS_XATTR=y |
1050 | # CONFIG_EXT2_FS_POSIX_ACL is not set | 1247 | CONFIG_EXT2_FS_POSIX_ACL=y |
1051 | # CONFIG_EXT2_FS_SECURITY is not set | 1248 | CONFIG_EXT2_FS_SECURITY=y |
1052 | # CONFIG_EXT2_FS_XIP is not set | 1249 | CONFIG_EXT2_FS_XIP=y |
1053 | CONFIG_EXT3_FS=y | 1250 | CONFIG_EXT3_FS=m |
1251 | CONFIG_EXT3_DEFAULTS_TO_ORDERED=y | ||
1054 | CONFIG_EXT3_FS_XATTR=y | 1252 | CONFIG_EXT3_FS_XATTR=y |
1055 | # CONFIG_EXT3_FS_POSIX_ACL is not set | 1253 | CONFIG_EXT3_FS_POSIX_ACL=y |
1056 | # CONFIG_EXT3_FS_SECURITY is not set | 1254 | CONFIG_EXT3_FS_SECURITY=y |
1057 | # CONFIG_EXT4DEV_FS is not set | 1255 | CONFIG_EXT4_FS=y |
1058 | CONFIG_JBD=y | 1256 | CONFIG_EXT4_FS_XATTR=y |
1257 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
1258 | CONFIG_EXT4_FS_SECURITY=y | ||
1259 | # CONFIG_EXT4_DEBUG is not set | ||
1260 | CONFIG_FS_XIP=y | ||
1261 | CONFIG_JBD=m | ||
1262 | CONFIG_JBD2=y | ||
1059 | CONFIG_FS_MBCACHE=y | 1263 | CONFIG_FS_MBCACHE=y |
1060 | # CONFIG_REISERFS_FS is not set | 1264 | # CONFIG_REISERFS_FS is not set |
1061 | # CONFIG_JFS_FS is not set | 1265 | # CONFIG_JFS_FS is not set |
1062 | # CONFIG_FS_POSIX_ACL is not set | 1266 | CONFIG_FS_POSIX_ACL=y |
1063 | # CONFIG_XFS_FS is not set | 1267 | # CONFIG_XFS_FS is not set |
1064 | # CONFIG_GFS2_FS is not set | 1268 | # CONFIG_GFS2_FS is not set |
1065 | # CONFIG_OCFS2_FS is not set | 1269 | # CONFIG_OCFS2_FS is not set |
1270 | # CONFIG_BTRFS_FS is not set | ||
1271 | # CONFIG_NILFS2_FS is not set | ||
1272 | CONFIG_FILE_LOCKING=y | ||
1273 | CONFIG_FSNOTIFY=y | ||
1066 | CONFIG_DNOTIFY=y | 1274 | CONFIG_DNOTIFY=y |
1067 | CONFIG_INOTIFY=y | 1275 | CONFIG_INOTIFY=y |
1068 | CONFIG_INOTIFY_USER=y | 1276 | CONFIG_INOTIFY_USER=y |
1069 | CONFIG_QUOTA=y | 1277 | CONFIG_QUOTA=y |
1070 | CONFIG_QUOTA_NETLINK_INTERFACE=y | 1278 | CONFIG_QUOTA_NETLINK_INTERFACE=y |
1071 | # CONFIG_PRINT_QUOTA_WARNING is not set | 1279 | # CONFIG_PRINT_QUOTA_WARNING is not set |
1280 | CONFIG_QUOTA_TREE=m | ||
1072 | # CONFIG_QFMT_V1 is not set | 1281 | # CONFIG_QFMT_V1 is not set |
1073 | CONFIG_QFMT_V2=m | 1282 | CONFIG_QFMT_V2=m |
1074 | CONFIG_QUOTACTL=y | 1283 | CONFIG_QUOTACTL=y |
1075 | CONFIG_AUTOFS_FS=m | 1284 | CONFIG_AUTOFS_FS=m |
1076 | CONFIG_AUTOFS4_FS=m | 1285 | CONFIG_AUTOFS4_FS=m |
1077 | CONFIG_FUSE_FS=m | 1286 | CONFIG_FUSE_FS=m |
1287 | # CONFIG_CUSE is not set | ||
1288 | |||
1289 | # | ||
1290 | # Caches | ||
1291 | # | ||
1292 | # CONFIG_FSCACHE is not set | ||
1078 | 1293 | ||
1079 | # | 1294 | # |
1080 | # CD-ROM/DVD Filesystems | 1295 | # CD-ROM/DVD Filesystems |
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y | |||
1103 | CONFIG_PROC_FS=y | 1318 | CONFIG_PROC_FS=y |
1104 | CONFIG_PROC_KCORE=y | 1319 | CONFIG_PROC_KCORE=y |
1105 | CONFIG_PROC_SYSCTL=y | 1320 | CONFIG_PROC_SYSCTL=y |
1321 | CONFIG_PROC_PAGE_MONITOR=y | ||
1106 | CONFIG_SYSFS=y | 1322 | CONFIG_SYSFS=y |
1107 | CONFIG_TMPFS=y | 1323 | CONFIG_TMPFS=y |
1108 | # CONFIG_TMPFS_POSIX_ACL is not set | 1324 | # CONFIG_TMPFS_POSIX_ACL is not set |
1109 | # CONFIG_HUGETLB_PAGE is not set | 1325 | # CONFIG_HUGETLB_PAGE is not set |
1110 | CONFIG_CONFIGFS_FS=m | 1326 | CONFIG_CONFIGFS_FS=m |
1111 | 1327 | CONFIG_MISC_FILESYSTEMS=y | |
1112 | # | ||
1113 | # Miscellaneous filesystems | ||
1114 | # | ||
1115 | # CONFIG_ADFS_FS is not set | 1328 | # CONFIG_ADFS_FS is not set |
1116 | # CONFIG_AFFS_FS is not set | 1329 | # CONFIG_AFFS_FS is not set |
1117 | # CONFIG_ECRYPT_FS is not set | 1330 | # CONFIG_ECRYPT_FS is not set |
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m | |||
1120 | # CONFIG_BEFS_FS is not set | 1333 | # CONFIG_BEFS_FS is not set |
1121 | # CONFIG_BFS_FS is not set | 1334 | # CONFIG_BFS_FS is not set |
1122 | # CONFIG_EFS_FS is not set | 1335 | # CONFIG_EFS_FS is not set |
1336 | # CONFIG_LOGFS is not set | ||
1123 | # CONFIG_CRAMFS is not set | 1337 | # CONFIG_CRAMFS is not set |
1338 | # CONFIG_SQUASHFS is not set | ||
1124 | # CONFIG_VXFS_FS is not set | 1339 | # CONFIG_VXFS_FS is not set |
1125 | # CONFIG_MINIX_FS is not set | 1340 | # CONFIG_MINIX_FS is not set |
1341 | # CONFIG_OMFS_FS is not set | ||
1126 | # CONFIG_HPFS_FS is not set | 1342 | # CONFIG_HPFS_FS is not set |
1127 | # CONFIG_QNX4FS_FS is not set | 1343 | # CONFIG_QNX4FS_FS is not set |
1128 | # CONFIG_ROMFS_FS is not set | 1344 | # CONFIG_ROMFS_FS is not set |
@@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y | |||
1133 | CONFIG_NFS_V3=y | 1349 | CONFIG_NFS_V3=y |
1134 | # CONFIG_NFS_V3_ACL is not set | 1350 | # CONFIG_NFS_V3_ACL is not set |
1135 | # CONFIG_NFS_V4 is not set | 1351 | # CONFIG_NFS_V4 is not set |
1136 | # CONFIG_NFSD is not set | ||
1137 | CONFIG_ROOT_NFS=y | 1352 | CONFIG_ROOT_NFS=y |
1353 | # CONFIG_NFSD is not set | ||
1138 | CONFIG_LOCKD=y | 1354 | CONFIG_LOCKD=y |
1139 | CONFIG_LOCKD_V4=y | 1355 | CONFIG_LOCKD_V4=y |
1140 | CONFIG_NFS_COMMON=y | 1356 | CONFIG_NFS_COMMON=y |
1141 | CONFIG_SUNRPC=y | 1357 | CONFIG_SUNRPC=y |
1142 | # CONFIG_SUNRPC_BIND34 is not set | 1358 | CONFIG_SUNRPC_GSS=m |
1143 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 1359 | CONFIG_RPCSEC_GSS_KRB5=m |
1144 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1360 | CONFIG_RPCSEC_GSS_SPKM3=m |
1145 | # CONFIG_SMB_FS is not set | 1361 | # CONFIG_SMB_FS is not set |
1362 | # CONFIG_CEPH_FS is not set | ||
1146 | # CONFIG_CIFS is not set | 1363 | # CONFIG_CIFS is not set |
1147 | # CONFIG_NCP_FS is not set | 1364 | # CONFIG_NCP_FS is not set |
1148 | # CONFIG_CODA_FS is not set | 1365 | # CONFIG_CODA_FS is not set |
@@ -1205,12 +1422,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y | |||
1205 | CONFIG_ENABLE_MUST_CHECK=y | 1422 | CONFIG_ENABLE_MUST_CHECK=y |
1206 | CONFIG_FRAME_WARN=2048 | 1423 | CONFIG_FRAME_WARN=2048 |
1207 | CONFIG_MAGIC_SYSRQ=y | 1424 | CONFIG_MAGIC_SYSRQ=y |
1425 | # CONFIG_STRIP_ASM_SYMS is not set | ||
1208 | # CONFIG_UNUSED_SYMBOLS is not set | 1426 | # CONFIG_UNUSED_SYMBOLS is not set |
1209 | # CONFIG_DEBUG_FS is not set | 1427 | # CONFIG_DEBUG_FS is not set |
1210 | # CONFIG_HEADERS_CHECK is not set | 1428 | # CONFIG_HEADERS_CHECK is not set |
1211 | CONFIG_DEBUG_KERNEL=y | 1429 | CONFIG_DEBUG_KERNEL=y |
1212 | # CONFIG_DEBUG_SHIRQ is not set | 1430 | # CONFIG_DEBUG_SHIRQ is not set |
1213 | CONFIG_DETECT_SOFTLOCKUP=y | 1431 | CONFIG_DETECT_SOFTLOCKUP=y |
1432 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
1433 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
1434 | CONFIG_DETECT_HUNG_TASK=y | ||
1435 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
1436 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
1214 | CONFIG_SCHED_DEBUG=y | 1437 | CONFIG_SCHED_DEBUG=y |
1215 | # CONFIG_SCHEDSTATS is not set | 1438 | # CONFIG_SCHEDSTATS is not set |
1216 | # CONFIG_TIMER_STATS is not set | 1439 | # CONFIG_TIMER_STATS is not set |
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y | |||
1219 | # CONFIG_DEBUG_RT_MUTEXES is not set | 1442 | # CONFIG_DEBUG_RT_MUTEXES is not set |
1220 | # CONFIG_RT_MUTEX_TESTER is not set | 1443 | # CONFIG_RT_MUTEX_TESTER is not set |
1221 | # CONFIG_DEBUG_SPINLOCK is not set | 1444 | # CONFIG_DEBUG_SPINLOCK is not set |
1222 | CONFIG_DEBUG_MUTEXES=y | 1445 | # CONFIG_DEBUG_MUTEXES is not set |
1223 | # CONFIG_DEBUG_LOCK_ALLOC is not set | 1446 | # CONFIG_DEBUG_LOCK_ALLOC is not set |
1224 | # CONFIG_PROVE_LOCKING is not set | 1447 | # CONFIG_PROVE_LOCKING is not set |
1225 | # CONFIG_LOCK_STAT is not set | 1448 | # CONFIG_LOCK_STAT is not set |
1226 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1449 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
1227 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | 1450 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
1228 | # CONFIG_DEBUG_KOBJECT is not set | 1451 | # CONFIG_DEBUG_KOBJECT is not set |
1229 | # CONFIG_DEBUG_INFO is not set | 1452 | # CONFIG_DEBUG_INFO is not set |
1230 | # CONFIG_DEBUG_VM is not set | 1453 | # CONFIG_DEBUG_VM is not set |
1231 | # CONFIG_DEBUG_WRITECOUNT is not set | 1454 | # CONFIG_DEBUG_WRITECOUNT is not set |
1232 | # CONFIG_DEBUG_LIST is not set | 1455 | CONFIG_DEBUG_MEMORY_INIT=y |
1456 | CONFIG_DEBUG_LIST=y | ||
1233 | # CONFIG_DEBUG_SG is not set | 1457 | # CONFIG_DEBUG_SG is not set |
1458 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
1459 | # CONFIG_DEBUG_CREDENTIALS is not set | ||
1234 | # CONFIG_BOOT_PRINTK_DELAY is not set | 1460 | # CONFIG_BOOT_PRINTK_DELAY is not set |
1235 | # CONFIG_RCU_TORTURE_TEST is not set | 1461 | # CONFIG_RCU_TORTURE_TEST is not set |
1462 | CONFIG_RCU_CPU_STALL_DETECTOR=y | ||
1236 | # CONFIG_BACKTRACE_SELF_TEST is not set | 1463 | # CONFIG_BACKTRACE_SELF_TEST is not set |
1464 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
1465 | # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set | ||
1237 | # CONFIG_FAULT_INJECTION is not set | 1466 | # CONFIG_FAULT_INJECTION is not set |
1467 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
1468 | # CONFIG_PAGE_POISONING is not set | ||
1469 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
1470 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | ||
1471 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | ||
1472 | CONFIG_HAVE_DYNAMIC_FTRACE=y | ||
1473 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | ||
1474 | CONFIG_TRACING_SUPPORT=y | ||
1475 | CONFIG_FTRACE=y | ||
1476 | # CONFIG_FUNCTION_TRACER is not set | ||
1477 | # CONFIG_IRQSOFF_TRACER is not set | ||
1478 | # CONFIG_SCHED_TRACER is not set | ||
1479 | # CONFIG_ENABLE_DEFAULT_TRACERS is not set | ||
1480 | # CONFIG_BOOT_TRACER is not set | ||
1481 | CONFIG_BRANCH_PROFILE_NONE=y | ||
1482 | # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | ||
1483 | # CONFIG_PROFILE_ALL_BRANCHES is not set | ||
1484 | # CONFIG_STACK_TRACER is not set | ||
1485 | # CONFIG_KMEMTRACE is not set | ||
1486 | # CONFIG_WORKQUEUE_TRACER is not set | ||
1487 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
1238 | # CONFIG_SAMPLES is not set | 1488 | # CONFIG_SAMPLES is not set |
1489 | CONFIG_HAVE_ARCH_KGDB=y | ||
1490 | # CONFIG_KGDB is not set | ||
1491 | CONFIG_EARLY_PRINTK=y | ||
1239 | # CONFIG_CMDLINE_BOOL is not set | 1492 | # CONFIG_CMDLINE_BOOL is not set |
1240 | # CONFIG_DEBUG_STACK_USAGE is not set | 1493 | # CONFIG_DEBUG_STACK_USAGE is not set |
1241 | # CONFIG_SB1XXX_CORELIS is not set | 1494 | # CONFIG_SB1XXX_CORELIS is not set |
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y | |||
1246 | # | 1499 | # |
1247 | CONFIG_KEYS=y | 1500 | CONFIG_KEYS=y |
1248 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | 1501 | CONFIG_KEYS_DEBUG_PROC_KEYS=y |
1249 | # CONFIG_SECURITY is not set | 1502 | CONFIG_SECURITY=y |
1250 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | 1503 | # CONFIG_SECURITYFS is not set |
1504 | CONFIG_SECURITY_NETWORK=y | ||
1505 | CONFIG_SECURITY_NETWORK_XFRM=y | ||
1506 | # CONFIG_SECURITY_PATH is not set | ||
1507 | CONFIG_LSM_MMAP_MIN_ADDR=65536 | ||
1508 | CONFIG_SECURITY_SELINUX=y | ||
1509 | CONFIG_SECURITY_SELINUX_BOOTPARAM=y | ||
1510 | CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 | ||
1511 | CONFIG_SECURITY_SELINUX_DISABLE=y | ||
1512 | CONFIG_SECURITY_SELINUX_DEVELOP=y | ||
1513 | CONFIG_SECURITY_SELINUX_AVC_STATS=y | ||
1514 | CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 | ||
1515 | # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set | ||
1516 | # CONFIG_SECURITY_SMACK is not set | ||
1517 | # CONFIG_SECURITY_TOMOYO is not set | ||
1518 | # CONFIG_DEFAULT_SECURITY_SELINUX is not set | ||
1519 | # CONFIG_DEFAULT_SECURITY_SMACK is not set | ||
1520 | # CONFIG_DEFAULT_SECURITY_TOMOYO is not set | ||
1521 | CONFIG_DEFAULT_SECURITY_DAC=y | ||
1522 | CONFIG_DEFAULT_SECURITY="" | ||
1251 | CONFIG_CRYPTO=y | 1523 | CONFIG_CRYPTO=y |
1252 | 1524 | ||
1253 | # | 1525 | # |
1254 | # Crypto core or helper | 1526 | # Crypto core or helper |
1255 | # | 1527 | # |
1528 | # CONFIG_CRYPTO_FIPS is not set | ||
1256 | CONFIG_CRYPTO_ALGAPI=y | 1529 | CONFIG_CRYPTO_ALGAPI=y |
1530 | CONFIG_CRYPTO_ALGAPI2=y | ||
1257 | CONFIG_CRYPTO_AEAD=m | 1531 | CONFIG_CRYPTO_AEAD=m |
1532 | CONFIG_CRYPTO_AEAD2=y | ||
1258 | CONFIG_CRYPTO_BLKCIPHER=y | 1533 | CONFIG_CRYPTO_BLKCIPHER=y |
1534 | CONFIG_CRYPTO_BLKCIPHER2=y | ||
1259 | CONFIG_CRYPTO_HASH=y | 1535 | CONFIG_CRYPTO_HASH=y |
1536 | CONFIG_CRYPTO_HASH2=y | ||
1537 | CONFIG_CRYPTO_RNG=m | ||
1538 | CONFIG_CRYPTO_RNG2=y | ||
1539 | CONFIG_CRYPTO_PCOMP=y | ||
1260 | CONFIG_CRYPTO_MANAGER=y | 1540 | CONFIG_CRYPTO_MANAGER=y |
1541 | CONFIG_CRYPTO_MANAGER2=y | ||
1261 | CONFIG_CRYPTO_GF128MUL=m | 1542 | CONFIG_CRYPTO_GF128MUL=m |
1262 | CONFIG_CRYPTO_NULL=y | 1543 | CONFIG_CRYPTO_NULL=y |
1544 | # CONFIG_CRYPTO_PCRYPT is not set | ||
1545 | CONFIG_CRYPTO_WORKQUEUE=y | ||
1263 | # CONFIG_CRYPTO_CRYPTD is not set | 1546 | # CONFIG_CRYPTO_CRYPTD is not set |
1264 | CONFIG_CRYPTO_AUTHENC=m | 1547 | CONFIG_CRYPTO_AUTHENC=m |
1265 | # CONFIG_CRYPTO_TEST is not set | 1548 | # CONFIG_CRYPTO_TEST is not set |
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m | |||
1276 | # | 1559 | # |
1277 | CONFIG_CRYPTO_CBC=m | 1560 | CONFIG_CRYPTO_CBC=m |
1278 | CONFIG_CRYPTO_CTR=m | 1561 | CONFIG_CRYPTO_CTR=m |
1279 | # CONFIG_CRYPTO_CTS is not set | 1562 | CONFIG_CRYPTO_CTS=m |
1280 | CONFIG_CRYPTO_ECB=m | 1563 | CONFIG_CRYPTO_ECB=m |
1281 | CONFIG_CRYPTO_LRW=m | 1564 | CONFIG_CRYPTO_LRW=m |
1282 | CONFIG_CRYPTO_PCBC=m | 1565 | CONFIG_CRYPTO_PCBC=m |
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m | |||
1287 | # | 1570 | # |
1288 | CONFIG_CRYPTO_HMAC=y | 1571 | CONFIG_CRYPTO_HMAC=y |
1289 | CONFIG_CRYPTO_XCBC=m | 1572 | CONFIG_CRYPTO_XCBC=m |
1573 | CONFIG_CRYPTO_VMAC=m | ||
1290 | 1574 | ||
1291 | # | 1575 | # |
1292 | # Digest | 1576 | # Digest |
1293 | # | 1577 | # |
1294 | # CONFIG_CRYPTO_CRC32C is not set | 1578 | CONFIG_CRYPTO_CRC32C=m |
1579 | CONFIG_CRYPTO_GHASH=m | ||
1295 | CONFIG_CRYPTO_MD4=m | 1580 | CONFIG_CRYPTO_MD4=m |
1296 | CONFIG_CRYPTO_MD5=y | 1581 | CONFIG_CRYPTO_MD5=y |
1297 | CONFIG_CRYPTO_MICHAEL_MIC=m | 1582 | CONFIG_CRYPTO_MICHAEL_MIC=m |
1583 | CONFIG_CRYPTO_RMD128=m | ||
1584 | CONFIG_CRYPTO_RMD160=m | ||
1585 | CONFIG_CRYPTO_RMD256=m | ||
1586 | CONFIG_CRYPTO_RMD320=m | ||
1298 | CONFIG_CRYPTO_SHA1=m | 1587 | CONFIG_CRYPTO_SHA1=m |
1299 | CONFIG_CRYPTO_SHA256=m | 1588 | CONFIG_CRYPTO_SHA256=m |
1300 | CONFIG_CRYPTO_SHA512=m | 1589 | CONFIG_CRYPTO_SHA512=m |
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m | |||
1325 | # Compression | 1614 | # Compression |
1326 | # | 1615 | # |
1327 | CONFIG_CRYPTO_DEFLATE=m | 1616 | CONFIG_CRYPTO_DEFLATE=m |
1328 | # CONFIG_CRYPTO_LZO is not set | 1617 | CONFIG_CRYPTO_ZLIB=m |
1618 | CONFIG_CRYPTO_LZO=m | ||
1619 | |||
1620 | # | ||
1621 | # Random Number Generation | ||
1622 | # | ||
1623 | CONFIG_CRYPTO_ANSI_CPRNG=m | ||
1329 | CONFIG_CRYPTO_HW=y | 1624 | CONFIG_CRYPTO_HW=y |
1330 | # CONFIG_CRYPTO_DEV_HIFN_795X is not set | 1625 | # CONFIG_CRYPTO_DEV_HIFN_795X is not set |
1626 | # CONFIG_BINARY_PRINTF is not set | ||
1331 | 1627 | ||
1332 | # | 1628 | # |
1333 | # Library routines | 1629 | # Library routines |
1334 | # | 1630 | # |
1335 | CONFIG_BITREVERSE=y | 1631 | CONFIG_BITREVERSE=y |
1336 | # CONFIG_GENERIC_FIND_FIRST_BIT is not set | 1632 | CONFIG_GENERIC_FIND_LAST_BIT=y |
1337 | CONFIG_CRC_CCITT=m | 1633 | CONFIG_CRC_CCITT=m |
1338 | # CONFIG_CRC16 is not set | 1634 | CONFIG_CRC16=y |
1635 | CONFIG_CRC_T10DIF=m | ||
1339 | CONFIG_CRC_ITU_T=m | 1636 | CONFIG_CRC_ITU_T=m |
1340 | CONFIG_CRC32=y | 1637 | CONFIG_CRC32=y |
1341 | # CONFIG_CRC7 is not set | 1638 | CONFIG_CRC7=m |
1342 | CONFIG_LIBCRC32C=m | 1639 | CONFIG_LIBCRC32C=m |
1343 | CONFIG_AUDIT_GENERIC=y | 1640 | CONFIG_AUDIT_GENERIC=y |
1344 | CONFIG_ZLIB_INFLATE=m | 1641 | CONFIG_ZLIB_INFLATE=y |
1345 | CONFIG_ZLIB_DEFLATE=m | 1642 | CONFIG_ZLIB_DEFLATE=m |
1346 | CONFIG_PLIST=y | 1643 | CONFIG_LZO_COMPRESS=m |
1644 | CONFIG_LZO_DECOMPRESS=m | ||
1645 | CONFIG_DECOMPRESS_GZIP=y | ||
1347 | CONFIG_HAS_IOMEM=y | 1646 | CONFIG_HAS_IOMEM=y |
1348 | CONFIG_HAS_IOPORT=y | 1647 | CONFIG_HAS_IOPORT=y |
1349 | CONFIG_HAS_DMA=y | 1648 | CONFIG_HAS_DMA=y |
1649 | CONFIG_NLATTR=y | ||
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h index 1dd74fbdc09b..9252d9b50e59 100644 --- a/arch/mips/include/asm/abi.h +++ b/arch/mips/include/asm/abi.h | |||
@@ -13,12 +13,14 @@ | |||
13 | #include <asm/siginfo.h> | 13 | #include <asm/siginfo.h> |
14 | 14 | ||
15 | struct mips_abi { | 15 | struct mips_abi { |
16 | int (* const setup_frame)(struct k_sigaction * ka, | 16 | int (* const setup_frame)(void *sig_return, struct k_sigaction *ka, |
17 | struct pt_regs *regs, int signr, | 17 | struct pt_regs *regs, int signr, |
18 | sigset_t *set); | 18 | sigset_t *set); |
19 | int (* const setup_rt_frame)(struct k_sigaction * ka, | 19 | const unsigned long signal_return_offset; |
20 | int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka, | ||
20 | struct pt_regs *regs, int signr, | 21 | struct pt_regs *regs, int signr, |
21 | sigset_t *set, siginfo_t *info); | 22 | sigset_t *set, siginfo_t *info); |
23 | const unsigned long rt_signal_return_offset; | ||
22 | const unsigned long restart; | 24 | const unsigned long restart; |
23 | }; | 25 | }; |
24 | 26 | ||
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index e53d7bed5cda..ea77a42c5f8c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -310,6 +310,7 @@ do { \ | |||
310 | 310 | ||
311 | #endif /* CONFIG_64BIT */ | 311 | #endif /* CONFIG_64BIT */ |
312 | 312 | ||
313 | struct pt_regs; | ||
313 | struct task_struct; | 314 | struct task_struct; |
314 | 315 | ||
315 | extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); | 316 | extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); |
@@ -367,4 +368,8 @@ extern const char *__elf_platform; | |||
367 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) | 368 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
368 | #endif | 369 | #endif |
369 | 370 | ||
371 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | ||
372 | struct linux_binprm; | ||
373 | extern int arch_setup_additional_pages(struct linux_binprm *bprm, | ||
374 | int uses_interp); | ||
370 | #endif /* _ASM_ELF_H */ | 375 | #endif /* _ASM_ELF_H */ |
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index aecada6f6117..3b4092705567 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h | |||
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats { | |||
41 | DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); | 41 | DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); |
42 | 42 | ||
43 | #define MIPS_FPU_EMU_INC_STATS(M) \ | 43 | #define MIPS_FPU_EMU_INC_STATS(M) \ |
44 | cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M)) | 44 | do { \ |
45 | preempt_disable(); \ | ||
46 | __local_inc(&__get_cpu_var(fpuemustats).M); \ | ||
47 | preempt_enable(); \ | ||
48 | } while (0) | ||
45 | 49 | ||
46 | #else | 50 | #else |
47 | #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0) | 51 | #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0) |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index b12c4aca2cc9..96a2391ad85b 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | |||
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set { | |||
85 | RSET_TIMER, | 85 | RSET_TIMER, |
86 | RSET_WDT, | 86 | RSET_WDT, |
87 | RSET_UART0, | 87 | RSET_UART0, |
88 | RSET_UART1, | ||
88 | RSET_GPIO, | 89 | RSET_GPIO, |
89 | RSET_SPI, | 90 | RSET_SPI, |
90 | RSET_UDC0, | 91 | RSET_UDC0, |
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set { | |||
123 | #define BCM_6338_TIMER_BASE (0xfffe0200) | 124 | #define BCM_6338_TIMER_BASE (0xfffe0200) |
124 | #define BCM_6338_WDT_BASE (0xfffe021c) | 125 | #define BCM_6338_WDT_BASE (0xfffe021c) |
125 | #define BCM_6338_UART0_BASE (0xfffe0300) | 126 | #define BCM_6338_UART0_BASE (0xfffe0300) |
127 | #define BCM_6338_UART1_BASE (0xdeadbeef) | ||
126 | #define BCM_6338_GPIO_BASE (0xfffe0400) | 128 | #define BCM_6338_GPIO_BASE (0xfffe0400) |
127 | #define BCM_6338_SPI_BASE (0xfffe0c00) | 129 | #define BCM_6338_SPI_BASE (0xfffe0c00) |
128 | #define BCM_6338_UDC0_BASE (0xdeadbeef) | 130 | #define BCM_6338_UDC0_BASE (0xdeadbeef) |
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set { | |||
153 | #define BCM_6345_TIMER_BASE (0xfffe0200) | 155 | #define BCM_6345_TIMER_BASE (0xfffe0200) |
154 | #define BCM_6345_WDT_BASE (0xfffe021c) | 156 | #define BCM_6345_WDT_BASE (0xfffe021c) |
155 | #define BCM_6345_UART0_BASE (0xfffe0300) | 157 | #define BCM_6345_UART0_BASE (0xfffe0300) |
158 | #define BCM_6345_UART1_BASE (0xdeadbeef) | ||
156 | #define BCM_6345_GPIO_BASE (0xfffe0400) | 159 | #define BCM_6345_GPIO_BASE (0xfffe0400) |
157 | #define BCM_6345_SPI_BASE (0xdeadbeef) | 160 | #define BCM_6345_SPI_BASE (0xdeadbeef) |
158 | #define BCM_6345_UDC0_BASE (0xdeadbeef) | 161 | #define BCM_6345_UDC0_BASE (0xdeadbeef) |
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set { | |||
182 | #define BCM_6348_TIMER_BASE (0xfffe0200) | 185 | #define BCM_6348_TIMER_BASE (0xfffe0200) |
183 | #define BCM_6348_WDT_BASE (0xfffe021c) | 186 | #define BCM_6348_WDT_BASE (0xfffe021c) |
184 | #define BCM_6348_UART0_BASE (0xfffe0300) | 187 | #define BCM_6348_UART0_BASE (0xfffe0300) |
188 | #define BCM_6348_UART1_BASE (0xdeadbeef) | ||
185 | #define BCM_6348_GPIO_BASE (0xfffe0400) | 189 | #define BCM_6348_GPIO_BASE (0xfffe0400) |
186 | #define BCM_6348_SPI_BASE (0xfffe0c00) | 190 | #define BCM_6348_SPI_BASE (0xfffe0c00) |
187 | #define BCM_6348_UDC0_BASE (0xfffe1000) | 191 | #define BCM_6348_UDC0_BASE (0xfffe1000) |
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set { | |||
208 | #define BCM_6358_TIMER_BASE (0xfffe0040) | 212 | #define BCM_6358_TIMER_BASE (0xfffe0040) |
209 | #define BCM_6358_WDT_BASE (0xfffe005c) | 213 | #define BCM_6358_WDT_BASE (0xfffe005c) |
210 | #define BCM_6358_UART0_BASE (0xfffe0100) | 214 | #define BCM_6358_UART0_BASE (0xfffe0100) |
215 | #define BCM_6358_UART1_BASE (0xfffe0120) | ||
211 | #define BCM_6358_GPIO_BASE (0xfffe0080) | 216 | #define BCM_6358_GPIO_BASE (0xfffe0080) |
212 | #define BCM_6358_SPI_BASE (0xdeadbeef) | 217 | #define BCM_6358_SPI_BASE (0xdeadbeef) |
213 | #define BCM_6358_UDC0_BASE (0xfffe0800) | 218 | #define BCM_6358_UDC0_BASE (0xfffe0800) |
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
246 | return BCM_6338_WDT_BASE; | 251 | return BCM_6338_WDT_BASE; |
247 | case RSET_UART0: | 252 | case RSET_UART0: |
248 | return BCM_6338_UART0_BASE; | 253 | return BCM_6338_UART0_BASE; |
254 | case RSET_UART1: | ||
255 | return BCM_6338_UART1_BASE; | ||
249 | case RSET_GPIO: | 256 | case RSET_GPIO: |
250 | return BCM_6338_GPIO_BASE; | 257 | return BCM_6338_GPIO_BASE; |
251 | case RSET_SPI: | 258 | case RSET_SPI: |
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
292 | return BCM_6345_WDT_BASE; | 299 | return BCM_6345_WDT_BASE; |
293 | case RSET_UART0: | 300 | case RSET_UART0: |
294 | return BCM_6345_UART0_BASE; | 301 | return BCM_6345_UART0_BASE; |
302 | case RSET_UART1: | ||
303 | return BCM_6345_UART1_BASE; | ||
295 | case RSET_GPIO: | 304 | case RSET_GPIO: |
296 | return BCM_6345_GPIO_BASE; | 305 | return BCM_6345_GPIO_BASE; |
297 | case RSET_SPI: | 306 | case RSET_SPI: |
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
338 | return BCM_6348_WDT_BASE; | 347 | return BCM_6348_WDT_BASE; |
339 | case RSET_UART0: | 348 | case RSET_UART0: |
340 | return BCM_6348_UART0_BASE; | 349 | return BCM_6348_UART0_BASE; |
350 | case RSET_UART1: | ||
351 | return BCM_6348_UART1_BASE; | ||
341 | case RSET_GPIO: | 352 | case RSET_GPIO: |
342 | return BCM_6348_GPIO_BASE; | 353 | return BCM_6348_GPIO_BASE; |
343 | case RSET_SPI: | 354 | case RSET_SPI: |
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
384 | return BCM_6358_WDT_BASE; | 395 | return BCM_6358_WDT_BASE; |
385 | case RSET_UART0: | 396 | case RSET_UART0: |
386 | return BCM_6358_UART0_BASE; | 397 | return BCM_6358_UART0_BASE; |
398 | case RSET_UART1: | ||
399 | return BCM_6358_UART1_BASE; | ||
387 | case RSET_GPIO: | 400 | case RSET_GPIO: |
388 | return BCM_6358_GPIO_BASE; | 401 | return BCM_6358_GPIO_BASE; |
389 | case RSET_SPI: | 402 | case RSET_SPI: |
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | |||
429 | enum bcm63xx_irq { | 442 | enum bcm63xx_irq { |
430 | IRQ_TIMER = 0, | 443 | IRQ_TIMER = 0, |
431 | IRQ_UART0, | 444 | IRQ_UART0, |
445 | IRQ_UART1, | ||
432 | IRQ_DSL, | 446 | IRQ_DSL, |
433 | IRQ_ENET0, | 447 | IRQ_ENET0, |
434 | IRQ_ENET1, | 448 | IRQ_ENET1, |
@@ -510,6 +524,7 @@ enum bcm63xx_irq { | |||
510 | */ | 524 | */ |
511 | #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) | 525 | #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) |
512 | #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) | 526 | #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) |
527 | #define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3) | ||
513 | #define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) | 528 | #define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) |
514 | #define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) | 529 | #define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) |
515 | #define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) | 530 | #define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h new file mode 100644 index 000000000000..23c705baf171 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef BCM63XX_DEV_UART_H_ | ||
2 | #define BCM63XX_DEV_UART_H_ | ||
3 | |||
4 | int bcm63xx_uart_register(unsigned int id); | ||
5 | |||
6 | #endif /* BCM63XX_DEV_UART_H_ */ | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 76a0b7216af5..43d4da0b1e9f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | |||
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void) | |||
10 | switch (bcm63xx_get_cpu_id()) { | 10 | switch (bcm63xx_get_cpu_id()) { |
11 | case BCM6358_CPU_ID: | 11 | case BCM6358_CPU_ID: |
12 | return 40; | 12 | return 40; |
13 | case BCM6338_CPU_ID: | ||
14 | return 8; | ||
15 | case BCM6345_CPU_ID: | ||
16 | return 16; | ||
13 | case BCM6348_CPU_ID: | 17 | case BCM6348_CPU_ID: |
14 | default: | 18 | default: |
15 | return 37; | 19 | return 37; |
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index 6479090a4106..474daaa53497 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | |||
@@ -45,6 +45,8 @@ struct board_info { | |||
45 | unsigned int has_ohci0:1; | 45 | unsigned int has_ohci0:1; |
46 | unsigned int has_ehci0:1; | 46 | unsigned int has_ehci0:1; |
47 | unsigned int has_dsp:1; | 47 | unsigned int has_dsp:1; |
48 | unsigned int has_uart0:1; | ||
49 | unsigned int has_uart1:1; | ||
48 | 50 | ||
49 | /* ethernet config */ | 51 | /* ethernet config */ |
50 | struct bcm63xx_enet_platform_data enet0; | 52 | struct bcm63xx_enet_platform_data enet0; |
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h index 71742bac940d..f453c01d0672 100644 --- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #define cpu_has_smartmips 0 | 24 | #define cpu_has_smartmips 0 |
25 | #define cpu_has_vtag_icache 0 | 25 | #define cpu_has_vtag_icache 0 |
26 | 26 | ||
27 | #if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345)) | 27 | #if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338)) |
28 | #define cpu_has_dc_aliases 0 | 28 | #define cpu_has_dc_aliases 0 |
29 | #endif | 29 | #endif |
30 | 30 | ||
diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 7950ef4f032c..743385d7b5f2 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h | |||
@@ -16,7 +16,11 @@ | |||
16 | #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ | 16 | #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ |
17 | defined(CONFIG_SB1_PASS_2_WORKAROUNDS) | 17 | defined(CONFIG_SB1_PASS_2_WORKAROUNDS) |
18 | 18 | ||
19 | #define BCM1250_M3_WAR 1 | 19 | #ifndef __ASSEMBLY__ |
20 | extern int sb1250_m3_workaround_needed(void); | ||
21 | #endif | ||
22 | |||
23 | #define BCM1250_M3_WAR sb1250_m3_workaround_needed() | ||
20 | #define SIBYTE_1956_WAR 1 | 24 | #define SIBYTE_1956_WAR 1 |
21 | 25 | ||
22 | #else | 26 | #else |
diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h index 4063edd79623..c436138945a8 100644 --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h | |||
@@ -1,6 +1,9 @@ | |||
1 | #ifndef __ASM_MMU_H | 1 | #ifndef __ASM_MMU_H |
2 | #define __ASM_MMU_H | 2 | #define __ASM_MMU_H |
3 | 3 | ||
4 | typedef unsigned long mm_context_t[NR_CPUS]; | 4 | typedef struct { |
5 | unsigned long asid[NR_CPUS]; | ||
6 | void *vdso; | ||
7 | } mm_context_t; | ||
5 | 8 | ||
6 | #endif /* __ASM_MMU_H */ | 9 | #endif /* __ASM_MMU_H */ |
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 145bb81ccaa5..d9592733a7ba 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask; | |||
104 | 104 | ||
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | #define cpu_context(cpu, mm) ((mm)->context[cpu]) | 107 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) |
108 | #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) | 108 | #define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) |
109 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) | 109 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) |
110 | 110 | ||
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index ac32572430f4..a16beafcea91 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t; | |||
188 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 188 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ |
189 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 189 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
190 | 190 | ||
191 | #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) | 191 | #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \ |
192 | #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) | 192 | PHYS_OFFSET) |
193 | #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \ | ||
194 | PHYS_OFFSET) | ||
193 | 195 | ||
194 | #include <asm-generic/memory_model.h> | 196 | #include <asm-generic/memory_model.h> |
195 | #include <asm-generic/getorder.h> | 197 | #include <asm-generic/getorder.h> |
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 087a8884ef06..ab387910009a 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void); | |||
33 | 33 | ||
34 | extern unsigned int vced_count, vcei_count; | 34 | extern unsigned int vced_count, vcei_count; |
35 | 35 | ||
36 | /* | ||
37 | * A special page (the vdso) is mapped into all processes at the very | ||
38 | * top of the virtual memory space. | ||
39 | */ | ||
40 | #define SPECIAL_PAGES_SIZE PAGE_SIZE | ||
41 | |||
36 | #ifdef CONFIG_32BIT | 42 | #ifdef CONFIG_32BIT |
37 | /* | 43 | /* |
38 | * User space process size: 2GB. This is hardcoded into a few places, | 44 | * User space process size: 2GB. This is hardcoded into a few places, |
39 | * so don't change it unless you know what you are doing. | 45 | * so don't change it unless you know what you are doing. |
40 | */ | 46 | */ |
41 | #define TASK_SIZE 0x7fff8000UL | 47 | #define TASK_SIZE 0x7fff8000UL |
42 | #define STACK_TOP TASK_SIZE | 48 | #define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) |
43 | 49 | ||
44 | /* | 50 | /* |
45 | * This decides where the kernel will search for a free chunk of vm | 51 | * This decides where the kernel will search for a free chunk of vm |
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count; | |||
59 | #define TASK_SIZE32 0x7fff8000UL | 65 | #define TASK_SIZE32 0x7fff8000UL |
60 | #define TASK_SIZE 0x10000000000UL | 66 | #define TASK_SIZE 0x10000000000UL |
61 | #define STACK_TOP \ | 67 | #define STACK_TOP \ |
62 | (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) | 68 | (((test_thread_flag(TIF_32BIT_ADDR) ? \ |
69 | TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE) | ||
63 | 70 | ||
64 | /* | 71 | /* |
65 | * This decides where the kernel will search for a free chunk of vm | 72 | * This decides where the kernel will search for a free chunk of vm |
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 3b6da3330e32..c8419129e770 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h | |||
@@ -121,6 +121,25 @@ | |||
121 | .endm | 121 | .endm |
122 | #else | 122 | #else |
123 | .macro get_saved_sp /* Uniprocessor variation */ | 123 | .macro get_saved_sp /* Uniprocessor variation */ |
124 | #ifdef CONFIG_CPU_LOONGSON2F | ||
125 | /* | ||
126 | * Clear BTB (branch target buffer), forbid RAS (return address | ||
127 | * stack) to workaround the Out-of-order Issue in Loongson2F | ||
128 | * via its diagnostic register. | ||
129 | */ | ||
130 | move k0, ra | ||
131 | jal 1f | ||
132 | nop | ||
133 | 1: jal 1f | ||
134 | nop | ||
135 | 1: jal 1f | ||
136 | nop | ||
137 | 1: jal 1f | ||
138 | nop | ||
139 | 1: move ra, k0 | ||
140 | li k0, 3 | ||
141 | mtc0 k0, $22 | ||
142 | #endif /* CONFIG_CPU_LOONGSON2F */ | ||
124 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) | 143 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) |
125 | lui k1, %hi(kernelsp) | 144 | lui k1, %hi(kernelsp) |
126 | #else | 145 | #else |
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index b99bd07e199b..11a8b5252549 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw); | |||
84 | Ip_u1u2u3(_mfc0); | 84 | Ip_u1u2u3(_mfc0); |
85 | Ip_u1u2u3(_mtc0); | 85 | Ip_u1u2u3(_mtc0); |
86 | Ip_u2u1u3(_ori); | 86 | Ip_u2u1u3(_ori); |
87 | Ip_u3u1u2(_or); | ||
87 | Ip_u2s3u1(_pref); | 88 | Ip_u2s3u1(_pref); |
88 | Ip_0(_rfe); | 89 | Ip_0(_rfe); |
89 | Ip_u2s3u1(_sc); | 90 | Ip_u2s3u1(_sc); |
@@ -102,6 +103,7 @@ Ip_0(_tlbwr); | |||
102 | Ip_u3u1u2(_xor); | 103 | Ip_u3u1u2(_xor); |
103 | Ip_u2u1u3(_xori); | 104 | Ip_u2u1u3(_xori); |
104 | Ip_u2u1msbu3(_dins); | 105 | Ip_u2u1msbu3(_dins); |
106 | Ip_u1(_syscall); | ||
105 | 107 | ||
106 | /* Handle labels. */ | 108 | /* Handle labels. */ |
107 | struct uasm_label { | 109 | struct uasm_label { |
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h new file mode 100644 index 000000000000..cca56aa40ff4 --- /dev/null +++ b/arch/mips/include/asm/vdso.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2009 Cavium Networks | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_VDSO_H | ||
10 | #define __ASM_VDSO_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | |||
15 | #ifdef CONFIG_32BIT | ||
16 | struct mips_vdso { | ||
17 | u32 signal_trampoline[2]; | ||
18 | u32 rt_signal_trampoline[2]; | ||
19 | }; | ||
20 | #else /* !CONFIG_32BIT */ | ||
21 | struct mips_vdso { | ||
22 | u32 o32_signal_trampoline[2]; | ||
23 | u32 o32_rt_signal_trampoline[2]; | ||
24 | u32 rt_signal_trampoline[2]; | ||
25 | u32 n32_rt_signal_trampoline[2]; | ||
26 | }; | ||
27 | #endif /* CONFIG_32BIT */ | ||
28 | |||
29 | #endif /* __ASM_VDSO_H */ | ||
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index ef20957ca14b..7a6ac501cbb5 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds | |||
6 | 6 | ||
7 | obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | 7 | obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ |
8 | ptrace.o reset.o setup.o signal.o syscall.o \ | 8 | ptrace.o reset.o setup.o signal.o syscall.o \ |
9 | time.o topology.o traps.o unaligned.o watch.o | 9 | time.o topology.o traps.o unaligned.o watch.o vdso.o |
10 | 10 | ||
11 | ifdef CONFIG_FUNCTION_TRACER | 11 | ifdef CONFIG_FUNCTION_TRACER |
12 | CFLAGS_REMOVE_ftrace.o = -pg | 12 | CFLAGS_REMOVE_ftrace.o = -pg |
diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c index d7ca256e33ef..cefc6e259baf 100644 --- a/arch/mips/kernel/cpufreq/loongson2_clock.c +++ b/arch/mips/kernel/cpufreq/loongson2_clock.c | |||
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void) | |||
164 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); | 164 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); |
165 | } | 165 | } |
166 | EXPORT_SYMBOL_GPL(loongson2_cpu_wait); | 166 | EXPORT_SYMBOL_GPL(loongson2_cpu_wait); |
167 | |||
168 | MODULE_AUTHOR("Yanhua <yanh@lemote.com>"); | ||
169 | MODULE_DESCRIPTION("cpufreq driver for Loongson 2F"); | ||
170 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 463b71b90a00..99960940d4a4 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -63,8 +63,13 @@ void __noreturn cpu_idle(void) | |||
63 | 63 | ||
64 | smtc_idle_loop_hook(); | 64 | smtc_idle_loop_hook(); |
65 | #endif | 65 | #endif |
66 | if (cpu_wait) | 66 | |
67 | if (cpu_wait) { | ||
68 | /* Don't trace irqs off for idle */ | ||
69 | stop_critical_timings(); | ||
67 | (*cpu_wait)(); | 70 | (*cpu_wait)(); |
71 | start_critical_timings(); | ||
72 | } | ||
68 | } | 73 | } |
69 | #ifdef CONFIG_HOTPLUG_CPU | 74 | #ifdef CONFIG_HOTPLUG_CPU |
70 | if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && | 75 | if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && |
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 6c8e8c4246f7..10263b405981 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
@@ -26,11 +26,6 @@ | |||
26 | */ | 26 | */ |
27 | extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 27 | extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, |
28 | size_t frame_size); | 28 | size_t frame_size); |
29 | /* | ||
30 | * install trampoline code to get back from the sig handler | ||
31 | */ | ||
32 | extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); | ||
33 | |||
34 | /* Check and clear pending FPU exceptions in saved CSR */ | 29 | /* Check and clear pending FPU exceptions in saved CSR */ |
35 | extern int fpcsr_pending(unsigned int __user *fpcsr); | 30 | extern int fpcsr_pending(unsigned int __user *fpcsr); |
36 | 31 | ||
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index d0c68b5d717b..2099d5a4c4b7 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/ucontext.h> | 32 | #include <asm/ucontext.h> |
33 | #include <asm/cpu-features.h> | 33 | #include <asm/cpu-features.h> |
34 | #include <asm/war.h> | 34 | #include <asm/war.h> |
35 | #include <asm/vdso.h> | ||
35 | 36 | ||
36 | #include "signal-common.h" | 37 | #include "signal-common.h" |
37 | 38 | ||
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); | |||
44 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); | 45 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); |
45 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); | 46 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); |
46 | 47 | ||
47 | /* | ||
48 | * Horribly complicated - with the bloody RM9000 workarounds enabled | ||
49 | * the signal trampolines is moving to the end of the structure so we can | ||
50 | * increase the alignment without breaking software compatibility. | ||
51 | */ | ||
52 | #if ICACHE_REFILLS_WORKAROUND_WAR == 0 | ||
53 | |||
54 | struct sigframe { | 48 | struct sigframe { |
55 | u32 sf_ass[4]; /* argument save space for o32 */ | 49 | u32 sf_ass[4]; /* argument save space for o32 */ |
56 | u32 sf_code[2]; /* signal trampoline */ | 50 | u32 sf_pad[2]; /* Was: signal trampoline */ |
57 | struct sigcontext sf_sc; | 51 | struct sigcontext sf_sc; |
58 | sigset_t sf_mask; | 52 | sigset_t sf_mask; |
59 | }; | 53 | }; |
60 | 54 | ||
61 | struct rt_sigframe { | 55 | struct rt_sigframe { |
62 | u32 rs_ass[4]; /* argument save space for o32 */ | 56 | u32 rs_ass[4]; /* argument save space for o32 */ |
63 | u32 rs_code[2]; /* signal trampoline */ | 57 | u32 rs_pad[2]; /* Was: signal trampoline */ |
64 | struct siginfo rs_info; | 58 | struct siginfo rs_info; |
65 | struct ucontext rs_uc; | 59 | struct ucontext rs_uc; |
66 | }; | 60 | }; |
67 | 61 | ||
68 | #else | ||
69 | |||
70 | struct sigframe { | ||
71 | u32 sf_ass[4]; /* argument save space for o32 */ | ||
72 | u32 sf_pad[2]; | ||
73 | struct sigcontext sf_sc; /* hw context */ | ||
74 | sigset_t sf_mask; | ||
75 | u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
76 | }; | ||
77 | |||
78 | struct rt_sigframe { | ||
79 | u32 rs_ass[4]; /* argument save space for o32 */ | ||
80 | u32 rs_pad[2]; | ||
81 | struct siginfo rs_info; | ||
82 | struct ucontext rs_uc; | ||
83 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
84 | }; | ||
85 | |||
86 | #endif | ||
87 | |||
88 | /* | 62 | /* |
89 | * Helper routines | 63 | * Helper routines |
90 | */ | 64 | */ |
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | |||
266 | return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); | 240 | return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); |
267 | } | 241 | } |
268 | 242 | ||
269 | int install_sigtramp(unsigned int __user *tramp, unsigned int syscall) | ||
270 | { | ||
271 | int err; | ||
272 | |||
273 | /* | ||
274 | * Set up the return code ... | ||
275 | * | ||
276 | * li v0, __NR__foo_sigreturn | ||
277 | * syscall | ||
278 | */ | ||
279 | |||
280 | err = __put_user(0x24020000 + syscall, tramp + 0); | ||
281 | err |= __put_user(0x0000000c , tramp + 1); | ||
282 | if (ICACHE_REFILLS_WORKAROUND_WAR) { | ||
283 | err |= __put_user(0, tramp + 2); | ||
284 | err |= __put_user(0, tramp + 3); | ||
285 | err |= __put_user(0, tramp + 4); | ||
286 | err |= __put_user(0, tramp + 5); | ||
287 | err |= __put_user(0, tramp + 6); | ||
288 | err |= __put_user(0, tramp + 7); | ||
289 | } | ||
290 | flush_cache_sigtramp((unsigned long) tramp); | ||
291 | |||
292 | return err; | ||
293 | } | ||
294 | |||
295 | /* | 243 | /* |
296 | * Atomically swap in the new signal mask, and wait for a signal. | 244 | * Atomically swap in the new signal mask, and wait for a signal. |
297 | */ | 245 | */ |
@@ -484,8 +432,8 @@ badframe: | |||
484 | } | 432 | } |
485 | 433 | ||
486 | #ifdef CONFIG_TRAD_SIGNALS | 434 | #ifdef CONFIG_TRAD_SIGNALS |
487 | static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | 435 | static int setup_frame(void *sig_return, struct k_sigaction *ka, |
488 | int signr, sigset_t *set) | 436 | struct pt_regs *regs, int signr, sigset_t *set) |
489 | { | 437 | { |
490 | struct sigframe __user *frame; | 438 | struct sigframe __user *frame; |
491 | int err = 0; | 439 | int err = 0; |
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
494 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 442 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
495 | goto give_sigsegv; | 443 | goto give_sigsegv; |
496 | 444 | ||
497 | err |= install_sigtramp(frame->sf_code, __NR_sigreturn); | ||
498 | |||
499 | err |= setup_sigcontext(regs, &frame->sf_sc); | 445 | err |= setup_sigcontext(regs, &frame->sf_sc); |
500 | err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); | 446 | err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); |
501 | if (err) | 447 | if (err) |
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
515 | regs->regs[ 5] = 0; | 461 | regs->regs[ 5] = 0; |
516 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; | 462 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; |
517 | regs->regs[29] = (unsigned long) frame; | 463 | regs->regs[29] = (unsigned long) frame; |
518 | regs->regs[31] = (unsigned long) frame->sf_code; | 464 | regs->regs[31] = (unsigned long) sig_return; |
519 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 465 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
520 | 466 | ||
521 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 467 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
@@ -529,8 +475,9 @@ give_sigsegv: | |||
529 | } | 475 | } |
530 | #endif | 476 | #endif |
531 | 477 | ||
532 | static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | 478 | static int setup_rt_frame(void *sig_return, struct k_sigaction *ka, |
533 | int signr, sigset_t *set, siginfo_t *info) | 479 | struct pt_regs *regs, int signr, sigset_t *set, |
480 | siginfo_t *info) | ||
534 | { | 481 | { |
535 | struct rt_sigframe __user *frame; | 482 | struct rt_sigframe __user *frame; |
536 | int err = 0; | 483 | int err = 0; |
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
539 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 486 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
540 | goto give_sigsegv; | 487 | goto give_sigsegv; |
541 | 488 | ||
542 | err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn); | ||
543 | |||
544 | /* Create siginfo. */ | 489 | /* Create siginfo. */ |
545 | err |= copy_siginfo_to_user(&frame->rs_info, info); | 490 | err |= copy_siginfo_to_user(&frame->rs_info, info); |
546 | 491 | ||
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
573 | regs->regs[ 5] = (unsigned long) &frame->rs_info; | 518 | regs->regs[ 5] = (unsigned long) &frame->rs_info; |
574 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; | 519 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; |
575 | regs->regs[29] = (unsigned long) frame; | 520 | regs->regs[29] = (unsigned long) frame; |
576 | regs->regs[31] = (unsigned long) frame->rs_code; | 521 | regs->regs[31] = (unsigned long) sig_return; |
577 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 522 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
578 | 523 | ||
579 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 524 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
@@ -590,8 +535,11 @@ give_sigsegv: | |||
590 | struct mips_abi mips_abi = { | 535 | struct mips_abi mips_abi = { |
591 | #ifdef CONFIG_TRAD_SIGNALS | 536 | #ifdef CONFIG_TRAD_SIGNALS |
592 | .setup_frame = setup_frame, | 537 | .setup_frame = setup_frame, |
538 | .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline), | ||
593 | #endif | 539 | #endif |
594 | .setup_rt_frame = setup_rt_frame, | 540 | .setup_rt_frame = setup_rt_frame, |
541 | .rt_signal_return_offset = | ||
542 | offsetof(struct mips_vdso, rt_signal_trampoline), | ||
595 | .restart = __NR_restart_syscall | 543 | .restart = __NR_restart_syscall |
596 | }; | 544 | }; |
597 | 545 | ||
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
599 | struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) | 547 | struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) |
600 | { | 548 | { |
601 | int ret; | 549 | int ret; |
550 | struct mips_abi *abi = current->thread.abi; | ||
551 | void *vdso = current->mm->context.vdso; | ||
602 | 552 | ||
603 | switch(regs->regs[0]) { | 553 | switch(regs->regs[0]) { |
604 | case ERESTART_RESTARTBLOCK: | 554 | case ERESTART_RESTARTBLOCK: |
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
619 | regs->regs[0] = 0; /* Don't deal with this again. */ | 569 | regs->regs[0] = 0; /* Don't deal with this again. */ |
620 | 570 | ||
621 | if (sig_uses_siginfo(ka)) | 571 | if (sig_uses_siginfo(ka)) |
622 | ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); | 572 | ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, |
573 | ka, regs, sig, oldset, info); | ||
623 | else | 574 | else |
624 | ret = current->thread.abi->setup_frame(ka, regs, sig, oldset); | 575 | ret = abi->setup_frame(vdso + abi->signal_return_offset, |
576 | ka, regs, sig, oldset); | ||
625 | 577 | ||
626 | spin_lock_irq(¤t->sighand->siglock); | 578 | spin_lock_irq(¤t->sighand->siglock); |
627 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 579 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 03abaf048f09..a0ed0e052b2e 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
33 | #include <asm/fpu.h> | 33 | #include <asm/fpu.h> |
34 | #include <asm/war.h> | 34 | #include <asm/war.h> |
35 | #include <asm/vdso.h> | ||
35 | 36 | ||
36 | #include "signal-common.h" | 37 | #include "signal-common.h" |
37 | 38 | ||
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user | |||
47 | /* | 48 | /* |
48 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | 49 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... |
49 | */ | 50 | */ |
50 | #define __NR_O32_sigreturn 4119 | ||
51 | #define __NR_O32_rt_sigreturn 4193 | ||
52 | #define __NR_O32_restart_syscall 4253 | 51 | #define __NR_O32_restart_syscall 4253 |
53 | 52 | ||
54 | /* 32-bit compatibility types */ | 53 | /* 32-bit compatibility types */ |
@@ -77,47 +76,20 @@ struct ucontext32 { | |||
77 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 76 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
78 | }; | 77 | }; |
79 | 78 | ||
80 | /* | ||
81 | * Horribly complicated - with the bloody RM9000 workarounds enabled | ||
82 | * the signal trampolines is moving to the end of the structure so we can | ||
83 | * increase the alignment without breaking software compatibility. | ||
84 | */ | ||
85 | #if ICACHE_REFILLS_WORKAROUND_WAR == 0 | ||
86 | |||
87 | struct sigframe32 { | 79 | struct sigframe32 { |
88 | u32 sf_ass[4]; /* argument save space for o32 */ | 80 | u32 sf_ass[4]; /* argument save space for o32 */ |
89 | u32 sf_code[2]; /* signal trampoline */ | 81 | u32 sf_pad[2]; /* Was: signal trampoline */ |
90 | struct sigcontext32 sf_sc; | 82 | struct sigcontext32 sf_sc; |
91 | compat_sigset_t sf_mask; | 83 | compat_sigset_t sf_mask; |
92 | }; | 84 | }; |
93 | 85 | ||
94 | struct rt_sigframe32 { | 86 | struct rt_sigframe32 { |
95 | u32 rs_ass[4]; /* argument save space for o32 */ | 87 | u32 rs_ass[4]; /* argument save space for o32 */ |
96 | u32 rs_code[2]; /* signal trampoline */ | 88 | u32 rs_pad[2]; /* Was: signal trampoline */ |
97 | compat_siginfo_t rs_info; | 89 | compat_siginfo_t rs_info; |
98 | struct ucontext32 rs_uc; | 90 | struct ucontext32 rs_uc; |
99 | }; | 91 | }; |
100 | 92 | ||
101 | #else /* ICACHE_REFILLS_WORKAROUND_WAR */ | ||
102 | |||
103 | struct sigframe32 { | ||
104 | u32 sf_ass[4]; /* argument save space for o32 */ | ||
105 | u32 sf_pad[2]; | ||
106 | struct sigcontext32 sf_sc; /* hw context */ | ||
107 | compat_sigset_t sf_mask; | ||
108 | u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
109 | }; | ||
110 | |||
111 | struct rt_sigframe32 { | ||
112 | u32 rs_ass[4]; /* argument save space for o32 */ | ||
113 | u32 rs_pad[2]; | ||
114 | compat_siginfo_t rs_info; | ||
115 | struct ucontext32 rs_uc; | ||
116 | u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */ | ||
117 | }; | ||
118 | |||
119 | #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ | ||
120 | |||
121 | /* | 93 | /* |
122 | * sigcontext handlers | 94 | * sigcontext handlers |
123 | */ | 95 | */ |
@@ -598,8 +570,8 @@ badframe: | |||
598 | force_sig(SIGSEGV, current); | 570 | force_sig(SIGSEGV, current); |
599 | } | 571 | } |
600 | 572 | ||
601 | static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 573 | static int setup_frame_32(void *sig_return, struct k_sigaction *ka, |
602 | int signr, sigset_t *set) | 574 | struct pt_regs *regs, int signr, sigset_t *set) |
603 | { | 575 | { |
604 | struct sigframe32 __user *frame; | 576 | struct sigframe32 __user *frame; |
605 | int err = 0; | 577 | int err = 0; |
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
608 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 580 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
609 | goto give_sigsegv; | 581 | goto give_sigsegv; |
610 | 582 | ||
611 | err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn); | ||
612 | |||
613 | err |= setup_sigcontext32(regs, &frame->sf_sc); | 583 | err |= setup_sigcontext32(regs, &frame->sf_sc); |
614 | err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); | 584 | err |= __copy_conv_sigset_to_user(&frame->sf_mask, set); |
615 | 585 | ||
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
630 | regs->regs[ 5] = 0; | 600 | regs->regs[ 5] = 0; |
631 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; | 601 | regs->regs[ 6] = (unsigned long) &frame->sf_sc; |
632 | regs->regs[29] = (unsigned long) frame; | 602 | regs->regs[29] = (unsigned long) frame; |
633 | regs->regs[31] = (unsigned long) frame->sf_code; | 603 | regs->regs[31] = (unsigned long) sig_return; |
634 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 604 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
635 | 605 | ||
636 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 606 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
@@ -644,8 +614,9 @@ give_sigsegv: | |||
644 | return -EFAULT; | 614 | return -EFAULT; |
645 | } | 615 | } |
646 | 616 | ||
647 | static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 617 | static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka, |
648 | int signr, sigset_t *set, siginfo_t *info) | 618 | struct pt_regs *regs, int signr, sigset_t *set, |
619 | siginfo_t *info) | ||
649 | { | 620 | { |
650 | struct rt_sigframe32 __user *frame; | 621 | struct rt_sigframe32 __user *frame; |
651 | int err = 0; | 622 | int err = 0; |
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
655 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 626 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
656 | goto give_sigsegv; | 627 | goto give_sigsegv; |
657 | 628 | ||
658 | err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn); | ||
659 | |||
660 | /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ | 629 | /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */ |
661 | err |= copy_siginfo_to_user32(&frame->rs_info, info); | 630 | err |= copy_siginfo_to_user32(&frame->rs_info, info); |
662 | 631 | ||
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
690 | regs->regs[ 5] = (unsigned long) &frame->rs_info; | 659 | regs->regs[ 5] = (unsigned long) &frame->rs_info; |
691 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; | 660 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; |
692 | regs->regs[29] = (unsigned long) frame; | 661 | regs->regs[29] = (unsigned long) frame; |
693 | regs->regs[31] = (unsigned long) frame->rs_code; | 662 | regs->regs[31] = (unsigned long) sig_return; |
694 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 663 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
695 | 664 | ||
696 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 665 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
@@ -709,7 +678,11 @@ give_sigsegv: | |||
709 | */ | 678 | */ |
710 | struct mips_abi mips_abi_32 = { | 679 | struct mips_abi mips_abi_32 = { |
711 | .setup_frame = setup_frame_32, | 680 | .setup_frame = setup_frame_32, |
681 | .signal_return_offset = | ||
682 | offsetof(struct mips_vdso, o32_signal_trampoline), | ||
712 | .setup_rt_frame = setup_rt_frame_32, | 683 | .setup_rt_frame = setup_rt_frame_32, |
684 | .rt_signal_return_offset = | ||
685 | offsetof(struct mips_vdso, o32_rt_signal_trampoline), | ||
713 | .restart = __NR_O32_restart_syscall | 686 | .restart = __NR_O32_restart_syscall |
714 | }; | 687 | }; |
715 | 688 | ||
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index bb277e82d421..2c5df818c65a 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
@@ -39,13 +39,13 @@ | |||
39 | #include <asm/fpu.h> | 39 | #include <asm/fpu.h> |
40 | #include <asm/cpu-features.h> | 40 | #include <asm/cpu-features.h> |
41 | #include <asm/war.h> | 41 | #include <asm/war.h> |
42 | #include <asm/vdso.h> | ||
42 | 43 | ||
43 | #include "signal-common.h" | 44 | #include "signal-common.h" |
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | 47 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... |
47 | */ | 48 | */ |
48 | #define __NR_N32_rt_sigreturn 6211 | ||
49 | #define __NR_N32_restart_syscall 6214 | 49 | #define __NR_N32_restart_syscall 6214 |
50 | 50 | ||
51 | extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); | 51 | extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); |
@@ -67,27 +67,13 @@ struct ucontextn32 { | |||
67 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 67 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #if ICACHE_REFILLS_WORKAROUND_WAR == 0 | ||
71 | |||
72 | struct rt_sigframe_n32 { | ||
73 | u32 rs_ass[4]; /* argument save space for o32 */ | ||
74 | u32 rs_code[2]; /* signal trampoline */ | ||
75 | struct compat_siginfo rs_info; | ||
76 | struct ucontextn32 rs_uc; | ||
77 | }; | ||
78 | |||
79 | #else /* ICACHE_REFILLS_WORKAROUND_WAR */ | ||
80 | |||
81 | struct rt_sigframe_n32 { | 70 | struct rt_sigframe_n32 { |
82 | u32 rs_ass[4]; /* argument save space for o32 */ | 71 | u32 rs_ass[4]; /* argument save space for o32 */ |
83 | u32 rs_pad[2]; | 72 | u32 rs_pad[2]; /* Was: signal trampoline */ |
84 | struct compat_siginfo rs_info; | 73 | struct compat_siginfo rs_info; |
85 | struct ucontextn32 rs_uc; | 74 | struct ucontextn32 rs_uc; |
86 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
87 | }; | 75 | }; |
88 | 76 | ||
89 | #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ | ||
90 | |||
91 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); | 77 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); |
92 | 78 | ||
93 | asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | 79 | asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) |
@@ -173,7 +159,7 @@ badframe: | |||
173 | force_sig(SIGSEGV, current); | 159 | force_sig(SIGSEGV, current); |
174 | } | 160 | } |
175 | 161 | ||
176 | static int setup_rt_frame_n32(struct k_sigaction * ka, | 162 | static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka, |
177 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) | 163 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) |
178 | { | 164 | { |
179 | struct rt_sigframe_n32 __user *frame; | 165 | struct rt_sigframe_n32 __user *frame; |
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka, | |||
184 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 170 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
185 | goto give_sigsegv; | 171 | goto give_sigsegv; |
186 | 172 | ||
187 | install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn); | ||
188 | |||
189 | /* Create siginfo. */ | 173 | /* Create siginfo. */ |
190 | err |= copy_siginfo_to_user32(&frame->rs_info, info); | 174 | err |= copy_siginfo_to_user32(&frame->rs_info, info); |
191 | 175 | ||
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka, | |||
219 | regs->regs[ 5] = (unsigned long) &frame->rs_info; | 203 | regs->regs[ 5] = (unsigned long) &frame->rs_info; |
220 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; | 204 | regs->regs[ 6] = (unsigned long) &frame->rs_uc; |
221 | regs->regs[29] = (unsigned long) frame; | 205 | regs->regs[29] = (unsigned long) frame; |
222 | regs->regs[31] = (unsigned long) frame->rs_code; | 206 | regs->regs[31] = (unsigned long) sig_return; |
223 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 207 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
224 | 208 | ||
225 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", | 209 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
@@ -235,5 +219,7 @@ give_sigsegv: | |||
235 | 219 | ||
236 | struct mips_abi mips_abi_n32 = { | 220 | struct mips_abi mips_abi_n32 = { |
237 | .setup_rt_frame = setup_rt_frame_n32, | 221 | .setup_rt_frame = setup_rt_frame_n32, |
222 | .rt_signal_return_offset = | ||
223 | offsetof(struct mips_vdso, n32_rt_signal_trampoline), | ||
238 | .restart = __NR_N32_restart_syscall | 224 | .restart = __NR_N32_restart_syscall |
239 | }; | 225 | }; |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 25e825aea327..a95dea5459c4 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -182,7 +182,7 @@ static int vpemask[2][8] = { | |||
182 | {0, 0, 0, 0, 0, 0, 0, 1} | 182 | {0, 0, 0, 0, 0, 0, 0, 1} |
183 | }; | 183 | }; |
184 | int tcnoprog[NR_CPUS]; | 184 | int tcnoprog[NR_CPUS]; |
185 | static atomic_t idle_hook_initialized = {0}; | 185 | static atomic_t idle_hook_initialized = ATOMIC_INIT(0); |
186 | static int clock_hang_reported[NR_CPUS]; | 186 | static int clock_hang_reported[NR_CPUS]; |
187 | 187 | ||
188 | #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ | 188 | #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 9587abc67f35..dd81b0f87518 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
79 | int do_color_align; | 79 | int do_color_align; |
80 | unsigned long task_size; | 80 | unsigned long task_size; |
81 | 81 | ||
82 | task_size = STACK_TOP; | 82 | #ifdef CONFIG_32BIT |
83 | task_size = TASK_SIZE; | ||
84 | #else /* Must be CONFIG_64BIT*/ | ||
85 | task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE; | ||
86 | #endif | ||
83 | 87 | ||
84 | if (len > task_size) | 88 | if (len > task_size) |
85 | return -ENOMEM; | 89 | return -ENOMEM; |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 4e00f9bc23ee..1a4dd657ccb9 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1599,7 +1599,7 @@ void __init trap_init(void) | |||
1599 | ebase = (unsigned long) | 1599 | ebase = (unsigned long) |
1600 | __alloc_bootmem(size, 1 << fls(size), 0); | 1600 | __alloc_bootmem(size, 1 << fls(size), 0); |
1601 | } else { | 1601 | } else { |
1602 | ebase = CAC_BASE; | 1602 | ebase = CKSEG0; |
1603 | if (cpu_has_mips_r2) | 1603 | if (cpu_has_mips_r2) |
1604 | ebase += (read_c0_ebase() & 0x3ffff000); | 1604 | ebase += (read_c0_ebase() & 0x3ffff000); |
1605 | } | 1605 | } |
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c new file mode 100644 index 000000000000..b773c1112b14 --- /dev/null +++ b/arch/mips/kernel/vdso.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2009, 2010 Cavium Networks, Inc. | ||
7 | */ | ||
8 | |||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/binfmts.h> | ||
16 | #include <linux/elf.h> | ||
17 | #include <linux/vmalloc.h> | ||
18 | #include <linux/unistd.h> | ||
19 | |||
20 | #include <asm/vdso.h> | ||
21 | #include <asm/uasm.h> | ||
22 | |||
23 | /* | ||
24 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | ||
25 | */ | ||
26 | #define __NR_O32_sigreturn 4119 | ||
27 | #define __NR_O32_rt_sigreturn 4193 | ||
28 | #define __NR_N32_rt_sigreturn 6211 | ||
29 | |||
30 | static struct page *vdso_page; | ||
31 | |||
32 | static void __init install_trampoline(u32 *tramp, unsigned int sigreturn) | ||
33 | { | ||
34 | uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */ | ||
35 | uasm_i_syscall(&tramp, 0); | ||
36 | } | ||
37 | |||
38 | static int __init init_vdso(void) | ||
39 | { | ||
40 | struct mips_vdso *vdso; | ||
41 | |||
42 | vdso_page = alloc_page(GFP_KERNEL); | ||
43 | if (!vdso_page) | ||
44 | panic("Cannot allocate vdso"); | ||
45 | |||
46 | vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL); | ||
47 | if (!vdso) | ||
48 | panic("Cannot map vdso"); | ||
49 | clear_page(vdso); | ||
50 | |||
51 | install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn); | ||
52 | #ifdef CONFIG_32BIT | ||
53 | install_trampoline(vdso->signal_trampoline, __NR_sigreturn); | ||
54 | #else | ||
55 | install_trampoline(vdso->n32_rt_signal_trampoline, | ||
56 | __NR_N32_rt_sigreturn); | ||
57 | install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn); | ||
58 | install_trampoline(vdso->o32_rt_signal_trampoline, | ||
59 | __NR_O32_rt_sigreturn); | ||
60 | #endif | ||
61 | |||
62 | vunmap(vdso); | ||
63 | |||
64 | pr_notice("init_vdso successfull\n"); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | device_initcall(init_vdso); | ||
69 | |||
70 | static unsigned long vdso_addr(unsigned long start) | ||
71 | { | ||
72 | return STACK_TOP; | ||
73 | } | ||
74 | |||
75 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | ||
76 | { | ||
77 | int ret; | ||
78 | unsigned long addr; | ||
79 | struct mm_struct *mm = current->mm; | ||
80 | |||
81 | down_write(&mm->mmap_sem); | ||
82 | |||
83 | addr = vdso_addr(mm->start_stack); | ||
84 | |||
85 | addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0); | ||
86 | if (IS_ERR_VALUE(addr)) { | ||
87 | ret = addr; | ||
88 | goto up_fail; | ||
89 | } | ||
90 | |||
91 | ret = install_special_mapping(mm, addr, PAGE_SIZE, | ||
92 | VM_READ|VM_EXEC| | ||
93 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| | ||
94 | VM_ALWAYSDUMP, | ||
95 | &vdso_page); | ||
96 | |||
97 | if (ret) | ||
98 | goto up_fail; | ||
99 | |||
100 | mm->context.vdso = (void *)addr; | ||
101 | |||
102 | up_fail: | ||
103 | up_write(&mm->mmap_sem); | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | const char *arch_vma_name(struct vm_area_struct *vma) | ||
108 | { | ||
109 | if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) | ||
110 | return "[vdso]"; | ||
111 | return NULL; | ||
112 | } | ||
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 6b3b1de9dcae..5995969e8c42 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c | |||
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay); | |||
41 | 41 | ||
42 | void __udelay(unsigned long us) | 42 | void __udelay(unsigned long us) |
43 | { | 43 | { |
44 | unsigned int lpj = current_cpu_data.udelay_val; | 44 | unsigned int lpj = raw_current_cpu_data.udelay_val; |
45 | 45 | ||
46 | __delay((us * 0x000010c7ull * HZ * lpj) >> 32); | 46 | __delay((us * 0x000010c7ull * HZ * lpj) >> 32); |
47 | } | 47 | } |
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay); | |||
49 | 49 | ||
50 | void __ndelay(unsigned long ns) | 50 | void __ndelay(unsigned long ns) |
51 | { | 51 | { |
52 | unsigned int lpj = current_cpu_data.udelay_val; | 52 | unsigned int lpj = raw_current_cpu_data.udelay_val; |
53 | 53 | ||
54 | __delay((ns * 0x00000005ull * HZ * lpj) >> 32); | 54 | __delay((ns * 0x00000005ull * HZ * lpj) >> 32); |
55 | } | 55 | } |
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h index 3f19d1c5d942..05909d58e2fe 100644 --- a/arch/mips/lib/libgcc.h +++ b/arch/mips/lib/libgcc.h | |||
@@ -17,8 +17,7 @@ struct DWstruct { | |||
17 | #error I feel sick. | 17 | #error I feel sick. |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | typedef union | 20 | typedef union { |
21 | { | ||
22 | struct DWstruct s; | 21 | struct DWstruct s; |
23 | long long ll; | 22 | long long ll; |
24 | } DWunion; | 23 | } DWunion; |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index be8627bc5b02..12af739048fa 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, | |||
133 | } | 133 | } |
134 | 134 | ||
135 | unsigned long _page_cachable_default; | 135 | unsigned long _page_cachable_default; |
136 | EXPORT_SYMBOL_GPL(_page_cachable_default); | 136 | EXPORT_SYMBOL(_page_cachable_default); |
137 | 137 | ||
138 | static inline void setup_protection_map(void) | 138 | static inline void setup_protection_map(void) |
139 | { | 139 | { |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0de0e4127d66..d1f68aadbc4c 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) | |||
788 | * create the plain linear handler | 788 | * create the plain linear handler |
789 | */ | 789 | */ |
790 | if (bcm1250_m3_war()) { | 790 | if (bcm1250_m3_war()) { |
791 | UASM_i_MFC0(&p, K0, C0_BADVADDR); | 791 | unsigned int segbits = 44; |
792 | UASM_i_MFC0(&p, K1, C0_ENTRYHI); | 792 | |
793 | uasm_i_dmfc0(&p, K0, C0_BADVADDR); | ||
794 | uasm_i_dmfc0(&p, K1, C0_ENTRYHI); | ||
793 | uasm_i_xor(&p, K0, K0, K1); | 795 | uasm_i_xor(&p, K0, K0, K1); |
794 | UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); | 796 | uasm_i_dsrl32(&p, K1, K0, 62 - 32); |
797 | uasm_i_dsrl(&p, K0, K0, 12 + 1); | ||
798 | uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); | ||
799 | uasm_i_or(&p, K0, K0, K1); | ||
795 | uasm_il_bnez(&p, &r, K0, label_leave); | 800 | uasm_il_bnez(&p, &r, K0, label_leave); |
796 | /* No need for uasm_i_nop */ | 801 | /* No need for uasm_i_nop */ |
797 | } | 802 | } |
@@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void) | |||
1312 | memset(relocs, 0, sizeof(relocs)); | 1317 | memset(relocs, 0, sizeof(relocs)); |
1313 | 1318 | ||
1314 | if (bcm1250_m3_war()) { | 1319 | if (bcm1250_m3_war()) { |
1315 | UASM_i_MFC0(&p, K0, C0_BADVADDR); | 1320 | unsigned int segbits = 44; |
1316 | UASM_i_MFC0(&p, K1, C0_ENTRYHI); | 1321 | |
1322 | uasm_i_dmfc0(&p, K0, C0_BADVADDR); | ||
1323 | uasm_i_dmfc0(&p, K1, C0_ENTRYHI); | ||
1317 | uasm_i_xor(&p, K0, K0, K1); | 1324 | uasm_i_xor(&p, K0, K0, K1); |
1318 | UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1); | 1325 | uasm_i_dsrl32(&p, K1, K0, 62 - 32); |
1326 | uasm_i_dsrl(&p, K0, K0, 12 + 1); | ||
1327 | uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32); | ||
1328 | uasm_i_or(&p, K0, K0, K1); | ||
1319 | uasm_il_bnez(&p, &r, K0, label_leave); | 1329 | uasm_il_bnez(&p, &r, K0, label_leave); |
1320 | /* No need for uasm_i_nop */ | 1330 | /* No need for uasm_i_nop */ |
1321 | } | 1331 | } |
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index 1581e9852461..611d564fdcf1 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -31,7 +31,8 @@ enum fields { | |||
31 | BIMM = 0x040, | 31 | BIMM = 0x040, |
32 | JIMM = 0x080, | 32 | JIMM = 0x080, |
33 | FUNC = 0x100, | 33 | FUNC = 0x100, |
34 | SET = 0x200 | 34 | SET = 0x200, |
35 | SCIMM = 0x400 | ||
35 | }; | 36 | }; |
36 | 37 | ||
37 | #define OP_MASK 0x3f | 38 | #define OP_MASK 0x3f |
@@ -52,6 +53,8 @@ enum fields { | |||
52 | #define FUNC_SH 0 | 53 | #define FUNC_SH 0 |
53 | #define SET_MASK 0x7 | 54 | #define SET_MASK 0x7 |
54 | #define SET_SH 0 | 55 | #define SET_SH 0 |
56 | #define SCIMM_MASK 0xfffff | ||
57 | #define SCIMM_SH 6 | ||
55 | 58 | ||
56 | enum opcode { | 59 | enum opcode { |
57 | insn_invalid, | 60 | insn_invalid, |
@@ -61,10 +64,10 @@ enum opcode { | |||
61 | insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, | 64 | insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, |
62 | insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, | 65 | insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal, |
63 | insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, | 66 | insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, |
64 | insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, | 67 | insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, |
65 | insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, | 68 | insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, |
66 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, | 69 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori, |
67 | insn_dins | 70 | insn_dins, insn_syscall |
68 | }; | 71 | }; |
69 | 72 | ||
70 | struct insn { | 73 | struct insn { |
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = { | |||
117 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 120 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
118 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | 121 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, |
119 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | 122 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, |
123 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | ||
120 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 124 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
121 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 125 | { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
122 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, | 126 | { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 }, |
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = { | |||
136 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | 140 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, |
137 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 141 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
138 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, | 142 | { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE }, |
143 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | ||
139 | { insn_invalid, 0, 0 } | 144 | { insn_invalid, 0, 0 } |
140 | }; | 145 | }; |
141 | 146 | ||
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg) | |||
208 | return (arg >> 2) & JIMM_MASK; | 213 | return (arg >> 2) & JIMM_MASK; |
209 | } | 214 | } |
210 | 215 | ||
216 | static inline __cpuinit u32 build_scimm(u32 arg) | ||
217 | { | ||
218 | if (arg & ~SCIMM_MASK) | ||
219 | printk(KERN_WARNING "Micro-assembler field overflow\n"); | ||
220 | |||
221 | return (arg & SCIMM_MASK) << SCIMM_SH; | ||
222 | } | ||
223 | |||
211 | static inline __cpuinit u32 build_func(u32 arg) | 224 | static inline __cpuinit u32 build_func(u32 arg) |
212 | { | 225 | { |
213 | if (arg & ~FUNC_MASK) | 226 | if (arg & ~FUNC_MASK) |
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...) | |||
266 | op |= build_func(va_arg(ap, u32)); | 279 | op |= build_func(va_arg(ap, u32)); |
267 | if (ip->fields & SET) | 280 | if (ip->fields & SET) |
268 | op |= build_set(va_arg(ap, u32)); | 281 | op |= build_set(va_arg(ap, u32)); |
282 | if (ip->fields & SCIMM) | ||
283 | op |= build_scimm(va_arg(ap, u32)); | ||
269 | va_end(ap); | 284 | va_end(ap); |
270 | 285 | ||
271 | **buf = op; | 286 | **buf = op; |
@@ -373,6 +388,7 @@ I_u2s3u1(_lw) | |||
373 | I_u1u2u3(_mfc0) | 388 | I_u1u2u3(_mfc0) |
374 | I_u1u2u3(_mtc0) | 389 | I_u1u2u3(_mtc0) |
375 | I_u2u1u3(_ori) | 390 | I_u2u1u3(_ori) |
391 | I_u3u1u2(_or) | ||
376 | I_u2s3u1(_pref) | 392 | I_u2s3u1(_pref) |
377 | I_0(_rfe) | 393 | I_0(_rfe) |
378 | I_u2s3u1(_sc) | 394 | I_u2s3u1(_sc) |
@@ -391,6 +407,7 @@ I_0(_tlbwr) | |||
391 | I_u3u1u2(_xor) | 407 | I_u3u1u2(_xor) |
392 | I_u2u1u3(_xori) | 408 | I_u2u1u3(_xori) |
393 | I_u2u1msbu3(_dins); | 409 | I_u2u1msbu3(_dins); |
410 | I_u1(_syscall); | ||
394 | 411 | ||
395 | /* Handle labels. */ | 412 | /* Handle labels. */ |
396 | void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) | 413 | void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) |
diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c index 2bb4057bf6c7..d657ee0bc131 100644 --- a/arch/mips/pci/ops-loongson2.c +++ b/arch/mips/pci/ops-loongson2.c | |||
@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = { | |||
180 | }; | 180 | }; |
181 | 181 | ||
182 | #ifdef CONFIG_CS5536 | 182 | #ifdef CONFIG_CS5536 |
183 | DEFINE_RAW_SPINLOCK(msr_lock); | ||
184 | |||
183 | void _rdmsr(u32 msr, u32 *hi, u32 *lo) | 185 | void _rdmsr(u32 msr, u32 *hi, u32 *lo) |
184 | { | 186 | { |
185 | struct pci_bus bus = { | 187 | struct pci_bus bus = { |
186 | .number = PCI_BUS_CS5536 | 188 | .number = PCI_BUS_CS5536 |
187 | }; | 189 | }; |
188 | u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); | 190 | u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); |
191 | unsigned long flags; | ||
192 | |||
193 | raw_spin_lock_irqsave(&msr_lock, flags); | ||
189 | loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); | 194 | loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); |
190 | loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); | 195 | loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); |
191 | loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); | 196 | loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); |
197 | raw_spin_unlock_irqrestore(&msr_lock, flags); | ||
192 | } | 198 | } |
193 | EXPORT_SYMBOL(_rdmsr); | 199 | EXPORT_SYMBOL(_rdmsr); |
194 | 200 | ||
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo) | |||
198 | .number = PCI_BUS_CS5536 | 204 | .number = PCI_BUS_CS5536 |
199 | }; | 205 | }; |
200 | u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); | 206 | u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0); |
207 | unsigned long flags; | ||
208 | |||
209 | raw_spin_lock_irqsave(&msr_lock, flags); | ||
201 | loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); | 210 | loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr); |
202 | loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); | 211 | loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo); |
203 | loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); | 212 | loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi); |
213 | raw_spin_unlock_irqrestore(&msr_lock, flags); | ||
204 | } | 214 | } |
205 | EXPORT_SYMBOL(_wrmsr); | 215 | EXPORT_SYMBOL(_wrmsr); |
206 | #endif | 216 | #endif |
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 0444da1e23c2..92da3155ce07 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c | |||
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void) | |||
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
89 | 89 | ||
90 | int sb1250_m3_workaround_needed(void) | ||
91 | { | ||
92 | switch (soc_type) { | ||
93 | case K_SYS_SOC_TYPE_BCM1250: | ||
94 | case K_SYS_SOC_TYPE_BCM1250_ALT: | ||
95 | case K_SYS_SOC_TYPE_BCM1250_ALT2: | ||
96 | case K_SYS_SOC_TYPE_BCM1125: | ||
97 | case K_SYS_SOC_TYPE_BCM1125H: | ||
98 | return soc_pass < K_SYS_REVISION_BCM1250_C0; | ||
99 | |||
100 | default: | ||
101 | return 0; | ||
102 | } | ||
103 | } | ||
104 | |||
90 | static int __init setup_bcm112x(void) | 105 | static int __init setup_bcm112x(void) |
91 | { | 106 | { |
92 | int ret = 0; | 107 | int ret = 0; |
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 81f3b0b5601e..6c5547d82bbe 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h | |||
@@ -77,4 +77,14 @@ struct kvm_debug_exit_arch { | |||
77 | struct kvm_guest_debug_arch { | 77 | struct kvm_guest_debug_arch { |
78 | }; | 78 | }; |
79 | 79 | ||
80 | #define KVM_REG_MASK 0x001f | ||
81 | #define KVM_REG_EXT_MASK 0xffe0 | ||
82 | #define KVM_REG_GPR 0x0000 | ||
83 | #define KVM_REG_FPR 0x0020 | ||
84 | #define KVM_REG_QPR 0x0040 | ||
85 | #define KVM_REG_FQPR 0x0060 | ||
86 | |||
87 | #define KVM_INTERRUPT_SET -1U | ||
88 | #define KVM_INTERRUPT_UNSET -2U | ||
89 | |||
80 | #endif /* __LINUX_KVM_POWERPC_H */ | 90 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index aadf2dd6f84e..7238c048e5bb 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
@@ -88,6 +88,7 @@ | |||
88 | 88 | ||
89 | #define BOOK3S_HFLAG_DCBZ32 0x1 | 89 | #define BOOK3S_HFLAG_DCBZ32 0x1 |
90 | #define BOOK3S_HFLAG_SLB 0x2 | 90 | #define BOOK3S_HFLAG_SLB 0x2 |
91 | #define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 | ||
91 | 92 | ||
92 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ | 93 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ |
93 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 94 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index db7db0a96967..ee7992189c6e 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -29,39 +29,40 @@ struct kvmppc_slb { | |||
29 | u64 vsid; | 29 | u64 vsid; |
30 | u64 orige; | 30 | u64 orige; |
31 | u64 origv; | 31 | u64 origv; |
32 | bool valid; | 32 | bool valid : 1; |
33 | bool Ks; | 33 | bool Ks : 1; |
34 | bool Kp; | 34 | bool Kp : 1; |
35 | bool nx; | 35 | bool nx : 1; |
36 | bool large; /* PTEs are 16MB */ | 36 | bool large : 1; /* PTEs are 16MB */ |
37 | bool tb; /* 1TB segment */ | 37 | bool tb : 1; /* 1TB segment */ |
38 | bool class; | 38 | bool class : 1; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct kvmppc_sr { | 41 | struct kvmppc_sr { |
42 | u32 raw; | 42 | u32 raw; |
43 | u32 vsid; | 43 | u32 vsid; |
44 | bool Ks; | 44 | bool Ks : 1; |
45 | bool Kp; | 45 | bool Kp : 1; |
46 | bool nx; | 46 | bool nx : 1; |
47 | bool valid : 1; | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | struct kvmppc_bat { | 50 | struct kvmppc_bat { |
50 | u64 raw; | 51 | u64 raw; |
51 | u32 bepi; | 52 | u32 bepi; |
52 | u32 bepi_mask; | 53 | u32 bepi_mask; |
53 | bool vs; | ||
54 | bool vp; | ||
55 | u32 brpn; | 54 | u32 brpn; |
56 | u8 wimg; | 55 | u8 wimg; |
57 | u8 pp; | 56 | u8 pp; |
57 | bool vs : 1; | ||
58 | bool vp : 1; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | struct kvmppc_sid_map { | 61 | struct kvmppc_sid_map { |
61 | u64 guest_vsid; | 62 | u64 guest_vsid; |
62 | u64 guest_esid; | 63 | u64 guest_esid; |
63 | u64 host_vsid; | 64 | u64 host_vsid; |
64 | bool valid; | 65 | bool valid : 1; |
65 | }; | 66 | }; |
66 | 67 | ||
67 | #define SID_MAP_BITS 9 | 68 | #define SID_MAP_BITS 9 |
@@ -82,9 +83,10 @@ struct kvmppc_vcpu_book3s { | |||
82 | struct kvmppc_bat ibat[8]; | 83 | struct kvmppc_bat ibat[8]; |
83 | struct kvmppc_bat dbat[8]; | 84 | struct kvmppc_bat dbat[8]; |
84 | u64 hid[6]; | 85 | u64 hid[6]; |
86 | u64 gqr[8]; | ||
85 | int slb_nr; | 87 | int slb_nr; |
88 | u32 dsisr; | ||
86 | u64 sdr1; | 89 | u64 sdr1; |
87 | u64 dsisr; | ||
88 | u64 hior; | 90 | u64 hior; |
89 | u64 msr_mask; | 91 | u64 msr_mask; |
90 | u64 vsid_first; | 92 | u64 vsid_first; |
@@ -98,11 +100,12 @@ struct kvmppc_vcpu_book3s { | |||
98 | #define CONTEXT_GUEST 1 | 100 | #define CONTEXT_GUEST 1 |
99 | #define CONTEXT_GUEST_END 2 | 101 | #define CONTEXT_GUEST_END 2 |
100 | 102 | ||
101 | #define VSID_REAL 0xfffffffffff00000 | 103 | #define VSID_REAL_DR 0x7ffffffffff00000ULL |
102 | #define VSID_REAL_DR 0xffffffffffe00000 | 104 | #define VSID_REAL_IR 0x7fffffffffe00000ULL |
103 | #define VSID_REAL_IR 0xffffffffffd00000 | 105 | #define VSID_SPLIT_MASK 0x7fffffffffe00000ULL |
104 | #define VSID_BAT 0xffffffffffc00000 | 106 | #define VSID_REAL 0x7fffffffffc00000ULL |
105 | #define VSID_PR 0x8000000000000000 | 107 | #define VSID_BAT 0x7fffffffffb00000ULL |
108 | #define VSID_PR 0x8000000000000000ULL | ||
106 | 109 | ||
107 | extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); | 110 | extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); |
108 | extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); | 111 | extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); |
@@ -114,11 +117,13 @@ extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); | |||
114 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); | 117 | extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); |
115 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); | 118 | extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); |
116 | extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); | 119 | extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); |
117 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data); | 120 | extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
118 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr); | 121 | extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data); |
119 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); | 122 | extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); |
120 | extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, | 123 | extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, |
121 | bool upper, u32 val); | 124 | bool upper, u32 val); |
125 | extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); | ||
126 | extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu); | ||
122 | 127 | ||
123 | extern u32 kvmppc_trampoline_lowmem; | 128 | extern u32 kvmppc_trampoline_lowmem; |
124 | extern u32 kvmppc_trampoline_enter; | 129 | extern u32 kvmppc_trampoline_enter; |
@@ -126,6 +131,8 @@ extern void kvmppc_rmcall(ulong srr0, ulong srr1); | |||
126 | extern void kvmppc_load_up_fpu(void); | 131 | extern void kvmppc_load_up_fpu(void); |
127 | extern void kvmppc_load_up_altivec(void); | 132 | extern void kvmppc_load_up_altivec(void); |
128 | extern void kvmppc_load_up_vsx(void); | 133 | extern void kvmppc_load_up_vsx(void); |
134 | extern u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst); | ||
135 | extern ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst); | ||
129 | 136 | ||
130 | static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) | 137 | static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) |
131 | { | 138 | { |
@@ -141,6 +148,11 @@ static inline ulong dsisr(void) | |||
141 | 148 | ||
142 | extern void kvm_return_point(void); | 149 | extern void kvm_return_point(void); |
143 | 150 | ||
151 | /* Magic register values loaded into r3 and r4 before the 'sc' assembly | ||
152 | * instruction for the OSI hypercalls */ | ||
153 | #define OSI_SC_MAGIC_R3 0x113724FA | ||
154 | #define OSI_SC_MAGIC_R4 0x77810F9B | ||
155 | |||
144 | #define INS_DCBZ 0x7c0007ec | 156 | #define INS_DCBZ 0x7c0007ec |
145 | 157 | ||
146 | #endif /* __ASM_KVM_BOOK3S_H__ */ | 158 | #endif /* __ASM_KVM_BOOK3S_H__ */ |
diff --git a/arch/powerpc/include/asm/kvm_fpu.h b/arch/powerpc/include/asm/kvm_fpu.h new file mode 100644 index 000000000000..94f05de9ad04 --- /dev/null +++ b/arch/powerpc/include/asm/kvm_fpu.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright Novell Inc. 2010 | ||
16 | * | ||
17 | * Authors: Alexander Graf <agraf@suse.de> | ||
18 | */ | ||
19 | |||
20 | #ifndef __ASM_KVM_FPU_H__ | ||
21 | #define __ASM_KVM_FPU_H__ | ||
22 | |||
23 | #include <linux/types.h> | ||
24 | |||
25 | extern void fps_fres(struct thread_struct *t, u32 *dst, u32 *src1); | ||
26 | extern void fps_frsqrte(struct thread_struct *t, u32 *dst, u32 *src1); | ||
27 | extern void fps_fsqrts(struct thread_struct *t, u32 *dst, u32 *src1); | ||
28 | |||
29 | extern void fps_fadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | ||
30 | extern void fps_fdivs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | ||
31 | extern void fps_fmuls(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | ||
32 | extern void fps_fsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2); | ||
33 | |||
34 | extern void fps_fmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | ||
35 | u32 *src3); | ||
36 | extern void fps_fmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | ||
37 | u32 *src3); | ||
38 | extern void fps_fnmadds(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | ||
39 | u32 *src3); | ||
40 | extern void fps_fnmsubs(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | ||
41 | u32 *src3); | ||
42 | extern void fps_fsel(struct thread_struct *t, u32 *dst, u32 *src1, u32 *src2, | ||
43 | u32 *src3); | ||
44 | |||
45 | #define FPD_ONE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ | ||
46 | u64 *dst, u64 *src1); | ||
47 | #define FPD_TWO_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ | ||
48 | u64 *dst, u64 *src1, u64 *src2); | ||
49 | #define FPD_THREE_IN(name) extern void fpd_ ## name(u64 *fpscr, u32 *cr, \ | ||
50 | u64 *dst, u64 *src1, u64 *src2, u64 *src3); | ||
51 | |||
52 | extern void fpd_fcmpu(u64 *fpscr, u32 *cr, u64 *src1, u64 *src2); | ||
53 | extern void fpd_fcmpo(u64 *fpscr, u32 *cr, u64 *src1, u64 *src2); | ||
54 | |||
55 | FPD_ONE_IN(fsqrts) | ||
56 | FPD_ONE_IN(frsqrtes) | ||
57 | FPD_ONE_IN(fres) | ||
58 | FPD_ONE_IN(frsp) | ||
59 | FPD_ONE_IN(fctiw) | ||
60 | FPD_ONE_IN(fctiwz) | ||
61 | FPD_ONE_IN(fsqrt) | ||
62 | FPD_ONE_IN(fre) | ||
63 | FPD_ONE_IN(frsqrte) | ||
64 | FPD_ONE_IN(fneg) | ||
65 | FPD_ONE_IN(fabs) | ||
66 | FPD_TWO_IN(fadds) | ||
67 | FPD_TWO_IN(fsubs) | ||
68 | FPD_TWO_IN(fdivs) | ||
69 | FPD_TWO_IN(fmuls) | ||
70 | FPD_TWO_IN(fcpsgn) | ||
71 | FPD_TWO_IN(fdiv) | ||
72 | FPD_TWO_IN(fadd) | ||
73 | FPD_TWO_IN(fmul) | ||
74 | FPD_TWO_IN(fsub) | ||
75 | FPD_THREE_IN(fmsubs) | ||
76 | FPD_THREE_IN(fmadds) | ||
77 | FPD_THREE_IN(fnmsubs) | ||
78 | FPD_THREE_IN(fnmadds) | ||
79 | FPD_THREE_IN(fsel) | ||
80 | FPD_THREE_IN(fmsub) | ||
81 | FPD_THREE_IN(fmadd) | ||
82 | FPD_THREE_IN(fnmsub) | ||
83 | FPD_THREE_IN(fnmadd) | ||
84 | |||
85 | #endif | ||
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5e5bae7e152f..5869a487e2e0 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -127,9 +127,9 @@ struct kvmppc_pte { | |||
127 | u64 eaddr; | 127 | u64 eaddr; |
128 | u64 vpage; | 128 | u64 vpage; |
129 | u64 raddr; | 129 | u64 raddr; |
130 | bool may_read; | 130 | bool may_read : 1; |
131 | bool may_write; | 131 | bool may_write : 1; |
132 | bool may_execute; | 132 | bool may_execute : 1; |
133 | }; | 133 | }; |
134 | 134 | ||
135 | struct kvmppc_mmu { | 135 | struct kvmppc_mmu { |
@@ -175,7 +175,7 @@ struct kvm_vcpu_arch { | |||
175 | ulong gpr[32]; | 175 | ulong gpr[32]; |
176 | 176 | ||
177 | u64 fpr[32]; | 177 | u64 fpr[32]; |
178 | u32 fpscr; | 178 | u64 fpscr; |
179 | 179 | ||
180 | #ifdef CONFIG_ALTIVEC | 180 | #ifdef CONFIG_ALTIVEC |
181 | vector128 vr[32]; | 181 | vector128 vr[32]; |
@@ -186,6 +186,11 @@ struct kvm_vcpu_arch { | |||
186 | u64 vsr[32]; | 186 | u64 vsr[32]; |
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | #ifdef CONFIG_PPC_BOOK3S | ||
190 | /* For Gekko paired singles */ | ||
191 | u32 qpr[32]; | ||
192 | #endif | ||
193 | |||
189 | ulong pc; | 194 | ulong pc; |
190 | ulong ctr; | 195 | ulong ctr; |
191 | ulong lr; | 196 | ulong lr; |
@@ -255,7 +260,7 @@ struct kvm_vcpu_arch { | |||
255 | 260 | ||
256 | u32 last_inst; | 261 | u32 last_inst; |
257 | #ifdef CONFIG_PPC64 | 262 | #ifdef CONFIG_PPC64 |
258 | ulong fault_dsisr; | 263 | u32 fault_dsisr; |
259 | #endif | 264 | #endif |
260 | ulong fault_dear; | 265 | ulong fault_dear; |
261 | ulong fault_esr; | 266 | ulong fault_esr; |
@@ -265,8 +270,11 @@ struct kvm_vcpu_arch { | |||
265 | 270 | ||
266 | u8 io_gpr; /* GPR used as IO source/target */ | 271 | u8 io_gpr; /* GPR used as IO source/target */ |
267 | u8 mmio_is_bigendian; | 272 | u8 mmio_is_bigendian; |
273 | u8 mmio_sign_extend; | ||
268 | u8 dcr_needed; | 274 | u8 dcr_needed; |
269 | u8 dcr_is_write; | 275 | u8 dcr_is_write; |
276 | u8 osi_needed; | ||
277 | u8 osi_enabled; | ||
270 | 278 | ||
271 | u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ | 279 | u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ |
272 | 280 | ||
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index e2642829e435..6a2464e4d6b9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -37,6 +37,7 @@ enum emulation_result { | |||
37 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ | 37 | EMULATE_DO_MMIO, /* kvm_run filled with MMIO request */ |
38 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ | 38 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ |
39 | EMULATE_FAIL, /* can't emulate this instruction */ | 39 | EMULATE_FAIL, /* can't emulate this instruction */ |
40 | EMULATE_AGAIN, /* something went wrong. go again */ | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 43 | extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
@@ -48,8 +49,11 @@ extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu); | |||
48 | extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | 49 | extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, |
49 | unsigned int rt, unsigned int bytes, | 50 | unsigned int rt, unsigned int bytes, |
50 | int is_bigendian); | 51 | int is_bigendian); |
52 | extern int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
53 | unsigned int rt, unsigned int bytes, | ||
54 | int is_bigendian); | ||
51 | extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | 55 | extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, |
52 | u32 val, unsigned int bytes, int is_bigendian); | 56 | u64 val, unsigned int bytes, int is_bigendian); |
53 | 57 | ||
54 | extern int kvmppc_emulate_instruction(struct kvm_run *run, | 58 | extern int kvmppc_emulate_instruction(struct kvm_run *run, |
55 | struct kvm_vcpu *vcpu); | 59 | struct kvm_vcpu *vcpu); |
@@ -88,6 +92,8 @@ extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); | |||
88 | extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); | 92 | extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); |
89 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | 93 | extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, |
90 | struct kvm_interrupt *irq); | 94 | struct kvm_interrupt *irq); |
95 | extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, | ||
96 | struct kvm_interrupt *irq); | ||
91 | 97 | ||
92 | extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | 98 | extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, |
93 | unsigned int op, int *advance); | 99 | unsigned int op, int *advance); |
@@ -99,6 +105,39 @@ extern void kvmppc_booke_exit(void); | |||
99 | 105 | ||
100 | extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); | 106 | extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); |
101 | 107 | ||
108 | /* | ||
109 | * Cuts out inst bits with ordering according to spec. | ||
110 | * That means the leftmost bit is zero. All given bits are included. | ||
111 | */ | ||
112 | static inline u32 kvmppc_get_field(u64 inst, int msb, int lsb) | ||
113 | { | ||
114 | u32 r; | ||
115 | u32 mask; | ||
116 | |||
117 | BUG_ON(msb > lsb); | ||
118 | |||
119 | mask = (1 << (lsb - msb + 1)) - 1; | ||
120 | r = (inst >> (63 - lsb)) & mask; | ||
121 | |||
122 | return r; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Replaces inst bits with ordering according to spec. | ||
127 | */ | ||
128 | static inline u32 kvmppc_set_field(u64 inst, int msb, int lsb, int value) | ||
129 | { | ||
130 | u32 r; | ||
131 | u32 mask; | ||
132 | |||
133 | BUG_ON(msb > lsb); | ||
134 | |||
135 | mask = ((1 << (lsb - msb + 1)) - 1) << (63 - lsb); | ||
136 | r = (inst & ~mask) | ((value << (63 - lsb)) & mask); | ||
137 | |||
138 | return r; | ||
139 | } | ||
140 | |||
102 | #ifdef CONFIG_PPC_BOOK3S | 141 | #ifdef CONFIG_PPC_BOOK3S |
103 | 142 | ||
104 | /* We assume we're always acting on the current vcpu */ | 143 | /* We assume we're always acting on the current vcpu */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5572e86223f4..8a69a39a10b1 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -293,10 +293,12 @@ | |||
293 | #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ | 293 | #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ |
294 | #define HID1_PS (1<<16) /* 750FX PLL selection */ | 294 | #define HID1_PS (1<<16) /* 750FX PLL selection */ |
295 | #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ | 295 | #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ |
296 | #define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */ | ||
296 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ | 297 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ |
297 | #define SPRN_IABR2 0x3FA /* 83xx */ | 298 | #define SPRN_IABR2 0x3FA /* 83xx */ |
298 | #define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */ | 299 | #define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */ |
299 | #define SPRN_HID4 0x3F4 /* 970 HID4 */ | 300 | #define SPRN_HID4 0x3F4 /* 970 HID4 */ |
301 | #define SPRN_HID4_GEKKO 0x3F3 /* Gekko HID4 */ | ||
300 | #define SPRN_HID5 0x3F6 /* 970 HID5 */ | 302 | #define SPRN_HID5 0x3F6 /* 970 HID5 */ |
301 | #define SPRN_HID6 0x3F9 /* BE HID 6 */ | 303 | #define SPRN_HID6 0x3F9 /* BE HID 6 */ |
302 | #define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ | 304 | #define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */ |
@@ -465,6 +467,14 @@ | |||
465 | #define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ | 467 | #define SPRN_VRSAVE 0x100 /* Vector Register Save Register */ |
466 | #define SPRN_XER 0x001 /* Fixed Point Exception Register */ | 468 | #define SPRN_XER 0x001 /* Fixed Point Exception Register */ |
467 | 469 | ||
470 | #define SPRN_MMCR0_GEKKO 0x3B8 /* Gekko Monitor Mode Control Register 0 */ | ||
471 | #define SPRN_MMCR1_GEKKO 0x3BC /* Gekko Monitor Mode Control Register 1 */ | ||
472 | #define SPRN_PMC1_GEKKO 0x3B9 /* Gekko Performance Monitor Control 1 */ | ||
473 | #define SPRN_PMC2_GEKKO 0x3BA /* Gekko Performance Monitor Control 2 */ | ||
474 | #define SPRN_PMC3_GEKKO 0x3BD /* Gekko Performance Monitor Control 3 */ | ||
475 | #define SPRN_PMC4_GEKKO 0x3BE /* Gekko Performance Monitor Control 4 */ | ||
476 | #define SPRN_WPAR_GEKKO 0x399 /* Gekko Write Pipe Address Register */ | ||
477 | |||
468 | #define SPRN_SCOMC 0x114 /* SCOM Access Control */ | 478 | #define SPRN_SCOMC 0x114 /* SCOM Access Control */ |
469 | #define SPRN_SCOMD 0x115 /* SCOM Access DATA */ | 479 | #define SPRN_SCOMD 0x115 /* SCOM Access DATA */ |
470 | 480 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index ab3e392ac63c..bc9f39d2598b 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -101,6 +101,10 @@ EXPORT_SYMBOL(pci_dram_offset); | |||
101 | EXPORT_SYMBOL(start_thread); | 101 | EXPORT_SYMBOL(start_thread); |
102 | EXPORT_SYMBOL(kernel_thread); | 102 | EXPORT_SYMBOL(kernel_thread); |
103 | 103 | ||
104 | #ifndef CONFIG_BOOKE | ||
105 | EXPORT_SYMBOL_GPL(cvt_df); | ||
106 | EXPORT_SYMBOL_GPL(cvt_fd); | ||
107 | #endif | ||
104 | EXPORT_SYMBOL(giveup_fpu); | 108 | EXPORT_SYMBOL(giveup_fpu); |
105 | #ifdef CONFIG_ALTIVEC | 109 | #ifdef CONFIG_ALTIVEC |
106 | EXPORT_SYMBOL(giveup_altivec); | 110 | EXPORT_SYMBOL(giveup_altivec); |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 56484d652377..eba721e39328 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -40,6 +40,8 @@ kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) | |||
40 | 40 | ||
41 | kvm-book3s_64-objs := \ | 41 | kvm-book3s_64-objs := \ |
42 | $(common-objs-y) \ | 42 | $(common-objs-y) \ |
43 | fpu.o \ | ||
44 | book3s_paired_singles.o \ | ||
43 | book3s.o \ | 45 | book3s.o \ |
44 | book3s_64_emulate.o \ | 46 | book3s_64_emulate.o \ |
45 | book3s_64_interrupts.o \ | 47 | book3s_64_interrupts.o \ |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 25da07fd9f77..41c23b636f53 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/gfp.h> | 29 | #include <linux/gfp.h> |
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
32 | #include <linux/highmem.h> | ||
32 | 33 | ||
33 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | 34 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU |
34 | 35 | ||
@@ -36,7 +37,8 @@ | |||
36 | /* #define EXIT_DEBUG_SIMPLE */ | 37 | /* #define EXIT_DEBUG_SIMPLE */ |
37 | /* #define DEBUG_EXT */ | 38 | /* #define DEBUG_EXT */ |
38 | 39 | ||
39 | static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr); | 40 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, |
41 | ulong msr); | ||
40 | 42 | ||
41 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 43 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
42 | { "exits", VCPU_STAT(sum_exits) }, | 44 | { "exits", VCPU_STAT(sum_exits) }, |
@@ -133,9 +135,21 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) | |||
133 | 135 | ||
134 | if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) || | 136 | if (((vcpu->arch.msr & (MSR_IR|MSR_DR)) != (old_msr & (MSR_IR|MSR_DR))) || |
135 | (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) { | 137 | (vcpu->arch.msr & MSR_PR) != (old_msr & MSR_PR)) { |
138 | bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; | ||
139 | bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; | ||
140 | |||
141 | /* Flush split mode PTEs */ | ||
142 | if (dr != ir) | ||
143 | kvmppc_mmu_pte_vflush(vcpu, VSID_SPLIT_MASK, | ||
144 | VSID_SPLIT_MASK); | ||
145 | |||
136 | kvmppc_mmu_flush_segments(vcpu); | 146 | kvmppc_mmu_flush_segments(vcpu); |
137 | kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); | 147 | kvmppc_mmu_map_segment(vcpu, vcpu->arch.pc); |
138 | } | 148 | } |
149 | |||
150 | /* Preload FPU if it's enabled */ | ||
151 | if (vcpu->arch.msr & MSR_FP) | ||
152 | kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); | ||
139 | } | 153 | } |
140 | 154 | ||
141 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) | 155 | void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) |
@@ -218,6 +232,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | |||
218 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); | 232 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); |
219 | } | 233 | } |
220 | 234 | ||
235 | void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, | ||
236 | struct kvm_interrupt *irq) | ||
237 | { | ||
238 | kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); | ||
239 | } | ||
240 | |||
221 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) | 241 | int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) |
222 | { | 242 | { |
223 | int deliver = 1; | 243 | int deliver = 1; |
@@ -337,6 +357,10 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) | |||
337 | !strcmp(cur_cpu_spec->platform, "ppc970")) | 357 | !strcmp(cur_cpu_spec->platform, "ppc970")) |
338 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; | 358 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; |
339 | 359 | ||
360 | /* Cell performs badly if MSR_FEx are set. So let's hope nobody | ||
361 | really needs them in a VM on Cell and force disable them. */ | ||
362 | if (!strcmp(cur_cpu_spec->platform, "ppc-cell-be")) | ||
363 | to_book3s(vcpu)->msr_mask &= ~(MSR_FE0 | MSR_FE1); | ||
340 | } | 364 | } |
341 | 365 | ||
342 | /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To | 366 | /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To |
@@ -350,34 +374,29 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) | |||
350 | */ | 374 | */ |
351 | static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) | 375 | static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte) |
352 | { | 376 | { |
353 | bool touched = false; | 377 | struct page *hpage; |
354 | hva_t hpage; | 378 | u64 hpage_offset; |
355 | u32 *page; | 379 | u32 *page; |
356 | int i; | 380 | int i; |
357 | 381 | ||
358 | hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT); | 382 | hpage = gfn_to_page(vcpu->kvm, pte->raddr >> PAGE_SHIFT); |
359 | if (kvm_is_error_hva(hpage)) | 383 | if (is_error_page(hpage)) |
360 | return; | 384 | return; |
361 | 385 | ||
362 | hpage |= pte->raddr & ~PAGE_MASK; | 386 | hpage_offset = pte->raddr & ~PAGE_MASK; |
363 | hpage &= ~0xFFFULL; | 387 | hpage_offset &= ~0xFFFULL; |
364 | 388 | hpage_offset /= 4; | |
365 | page = vmalloc(HW_PAGE_SIZE); | ||
366 | |||
367 | if (copy_from_user(page, (void __user *)hpage, HW_PAGE_SIZE)) | ||
368 | goto out; | ||
369 | 389 | ||
370 | for (i=0; i < HW_PAGE_SIZE / 4; i++) | 390 | get_page(hpage); |
371 | if ((page[i] & 0xff0007ff) == INS_DCBZ) { | 391 | page = kmap_atomic(hpage, KM_USER0); |
372 | page[i] &= 0xfffffff7; // reserved instruction, so we trap | ||
373 | touched = true; | ||
374 | } | ||
375 | 392 | ||
376 | if (touched) | 393 | /* patch dcbz into reserved instruction, so we trap */ |
377 | copy_to_user((void __user *)hpage, page, HW_PAGE_SIZE); | 394 | for (i=hpage_offset; i < hpage_offset + (HW_PAGE_SIZE / 4); i++) |
395 | if ((page[i] & 0xff0007ff) == INS_DCBZ) | ||
396 | page[i] &= 0xfffffff7; | ||
378 | 397 | ||
379 | out: | 398 | kunmap_atomic(page, KM_USER0); |
380 | vfree(page); | 399 | put_page(hpage); |
381 | } | 400 | } |
382 | 401 | ||
383 | static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | 402 | static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, |
@@ -391,15 +410,7 @@ static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, | |||
391 | } else { | 410 | } else { |
392 | pte->eaddr = eaddr; | 411 | pte->eaddr = eaddr; |
393 | pte->raddr = eaddr & 0xffffffff; | 412 | pte->raddr = eaddr & 0xffffffff; |
394 | pte->vpage = eaddr >> 12; | 413 | pte->vpage = VSID_REAL | eaddr >> 12; |
395 | switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { | ||
396 | case 0: | ||
397 | pte->vpage |= VSID_REAL; | ||
398 | case MSR_DR: | ||
399 | pte->vpage |= VSID_REAL_DR; | ||
400 | case MSR_IR: | ||
401 | pte->vpage |= VSID_REAL_IR; | ||
402 | } | ||
403 | pte->may_read = true; | 414 | pte->may_read = true; |
404 | pte->may_write = true; | 415 | pte->may_write = true; |
405 | pte->may_execute = true; | 416 | pte->may_execute = true; |
@@ -434,55 +445,55 @@ err: | |||
434 | return kvmppc_bad_hva(); | 445 | return kvmppc_bad_hva(); |
435 | } | 446 | } |
436 | 447 | ||
437 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr) | 448 | int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, |
449 | bool data) | ||
438 | { | 450 | { |
439 | struct kvmppc_pte pte; | 451 | struct kvmppc_pte pte; |
440 | hva_t hva = eaddr; | ||
441 | 452 | ||
442 | vcpu->stat.st++; | 453 | vcpu->stat.st++; |
443 | 454 | ||
444 | if (kvmppc_xlate(vcpu, eaddr, false, &pte)) | 455 | if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) |
445 | goto err; | 456 | return -ENOENT; |
446 | 457 | ||
447 | hva = kvmppc_pte_to_hva(vcpu, &pte, false); | 458 | *eaddr = pte.raddr; |
448 | if (kvm_is_error_hva(hva)) | ||
449 | goto err; | ||
450 | 459 | ||
451 | if (copy_to_user((void __user *)hva, ptr, size)) { | 460 | if (!pte.may_write) |
452 | printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva); | 461 | return -EPERM; |
453 | goto err; | ||
454 | } | ||
455 | 462 | ||
456 | return 0; | 463 | if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) |
464 | return EMULATE_DO_MMIO; | ||
457 | 465 | ||
458 | err: | 466 | return EMULATE_DONE; |
459 | return -ENOENT; | ||
460 | } | 467 | } |
461 | 468 | ||
462 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, | 469 | int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, |
463 | bool data) | 470 | bool data) |
464 | { | 471 | { |
465 | struct kvmppc_pte pte; | 472 | struct kvmppc_pte pte; |
466 | hva_t hva = eaddr; | 473 | hva_t hva = *eaddr; |
467 | 474 | ||
468 | vcpu->stat.ld++; | 475 | vcpu->stat.ld++; |
469 | 476 | ||
470 | if (kvmppc_xlate(vcpu, eaddr, data, &pte)) | 477 | if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) |
471 | goto err; | 478 | goto nopte; |
479 | |||
480 | *eaddr = pte.raddr; | ||
472 | 481 | ||
473 | hva = kvmppc_pte_to_hva(vcpu, &pte, true); | 482 | hva = kvmppc_pte_to_hva(vcpu, &pte, true); |
474 | if (kvm_is_error_hva(hva)) | 483 | if (kvm_is_error_hva(hva)) |
475 | goto err; | 484 | goto mmio; |
476 | 485 | ||
477 | if (copy_from_user(ptr, (void __user *)hva, size)) { | 486 | if (copy_from_user(ptr, (void __user *)hva, size)) { |
478 | printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); | 487 | printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); |
479 | goto err; | 488 | goto mmio; |
480 | } | 489 | } |
481 | 490 | ||
482 | return 0; | 491 | return EMULATE_DONE; |
483 | 492 | ||
484 | err: | 493 | nopte: |
485 | return -ENOENT; | 494 | return -ENOENT; |
495 | mmio: | ||
496 | return EMULATE_DO_MMIO; | ||
486 | } | 497 | } |
487 | 498 | ||
488 | static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) | 499 | static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) |
@@ -499,12 +510,10 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
499 | int page_found = 0; | 510 | int page_found = 0; |
500 | struct kvmppc_pte pte; | 511 | struct kvmppc_pte pte; |
501 | bool is_mmio = false; | 512 | bool is_mmio = false; |
513 | bool dr = (vcpu->arch.msr & MSR_DR) ? true : false; | ||
514 | bool ir = (vcpu->arch.msr & MSR_IR) ? true : false; | ||
502 | 515 | ||
503 | if ( vec == BOOK3S_INTERRUPT_DATA_STORAGE ) { | 516 | relocated = data ? dr : ir; |
504 | relocated = (vcpu->arch.msr & MSR_DR); | ||
505 | } else { | ||
506 | relocated = (vcpu->arch.msr & MSR_IR); | ||
507 | } | ||
508 | 517 | ||
509 | /* Resolve real address if translation turned on */ | 518 | /* Resolve real address if translation turned on */ |
510 | if (relocated) { | 519 | if (relocated) { |
@@ -516,14 +525,18 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
516 | pte.raddr = eaddr & 0xffffffff; | 525 | pte.raddr = eaddr & 0xffffffff; |
517 | pte.eaddr = eaddr; | 526 | pte.eaddr = eaddr; |
518 | pte.vpage = eaddr >> 12; | 527 | pte.vpage = eaddr >> 12; |
519 | switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { | 528 | } |
520 | case 0: | 529 | |
521 | pte.vpage |= VSID_REAL; | 530 | switch (vcpu->arch.msr & (MSR_DR|MSR_IR)) { |
522 | case MSR_DR: | 531 | case 0: |
523 | pte.vpage |= VSID_REAL_DR; | 532 | pte.vpage |= VSID_REAL; |
524 | case MSR_IR: | 533 | break; |
525 | pte.vpage |= VSID_REAL_IR; | 534 | case MSR_DR: |
526 | } | 535 | pte.vpage |= VSID_REAL_DR; |
536 | break; | ||
537 | case MSR_IR: | ||
538 | pte.vpage |= VSID_REAL_IR; | ||
539 | break; | ||
527 | } | 540 | } |
528 | 541 | ||
529 | if (vcpu->arch.mmu.is_dcbz32(vcpu) && | 542 | if (vcpu->arch.mmu.is_dcbz32(vcpu) && |
@@ -583,11 +596,13 @@ static inline int get_fpr_index(int i) | |||
583 | } | 596 | } |
584 | 597 | ||
585 | /* Give up external provider (FPU, Altivec, VSX) */ | 598 | /* Give up external provider (FPU, Altivec, VSX) */ |
586 | static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) | 599 | void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) |
587 | { | 600 | { |
588 | struct thread_struct *t = ¤t->thread; | 601 | struct thread_struct *t = ¤t->thread; |
589 | u64 *vcpu_fpr = vcpu->arch.fpr; | 602 | u64 *vcpu_fpr = vcpu->arch.fpr; |
603 | #ifdef CONFIG_VSX | ||
590 | u64 *vcpu_vsx = vcpu->arch.vsr; | 604 | u64 *vcpu_vsx = vcpu->arch.vsr; |
605 | #endif | ||
591 | u64 *thread_fpr = (u64*)t->fpr; | 606 | u64 *thread_fpr = (u64*)t->fpr; |
592 | int i; | 607 | int i; |
593 | 608 | ||
@@ -629,21 +644,64 @@ static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) | |||
629 | kvmppc_recalc_shadow_msr(vcpu); | 644 | kvmppc_recalc_shadow_msr(vcpu); |
630 | } | 645 | } |
631 | 646 | ||
647 | static int kvmppc_read_inst(struct kvm_vcpu *vcpu) | ||
648 | { | ||
649 | ulong srr0 = vcpu->arch.pc; | ||
650 | int ret; | ||
651 | |||
652 | ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &vcpu->arch.last_inst, false); | ||
653 | if (ret == -ENOENT) { | ||
654 | vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1); | ||
655 | vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0); | ||
656 | vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0); | ||
657 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE); | ||
658 | return EMULATE_AGAIN; | ||
659 | } | ||
660 | |||
661 | return EMULATE_DONE; | ||
662 | } | ||
663 | |||
664 | static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr) | ||
665 | { | ||
666 | |||
667 | /* Need to do paired single emulation? */ | ||
668 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) | ||
669 | return EMULATE_DONE; | ||
670 | |||
671 | /* Read out the instruction */ | ||
672 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) | ||
673 | /* Need to emulate */ | ||
674 | return EMULATE_FAIL; | ||
675 | |||
676 | return EMULATE_AGAIN; | ||
677 | } | ||
678 | |||
632 | /* Handle external providers (FPU, Altivec, VSX) */ | 679 | /* Handle external providers (FPU, Altivec, VSX) */ |
633 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, | 680 | static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, |
634 | ulong msr) | 681 | ulong msr) |
635 | { | 682 | { |
636 | struct thread_struct *t = ¤t->thread; | 683 | struct thread_struct *t = ¤t->thread; |
637 | u64 *vcpu_fpr = vcpu->arch.fpr; | 684 | u64 *vcpu_fpr = vcpu->arch.fpr; |
685 | #ifdef CONFIG_VSX | ||
638 | u64 *vcpu_vsx = vcpu->arch.vsr; | 686 | u64 *vcpu_vsx = vcpu->arch.vsr; |
687 | #endif | ||
639 | u64 *thread_fpr = (u64*)t->fpr; | 688 | u64 *thread_fpr = (u64*)t->fpr; |
640 | int i; | 689 | int i; |
641 | 690 | ||
691 | /* When we have paired singles, we emulate in software */ | ||
692 | if (vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE) | ||
693 | return RESUME_GUEST; | ||
694 | |||
642 | if (!(vcpu->arch.msr & msr)) { | 695 | if (!(vcpu->arch.msr & msr)) { |
643 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); | 696 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); |
644 | return RESUME_GUEST; | 697 | return RESUME_GUEST; |
645 | } | 698 | } |
646 | 699 | ||
700 | /* We already own the ext */ | ||
701 | if (vcpu->arch.guest_owned_ext & msr) { | ||
702 | return RESUME_GUEST; | ||
703 | } | ||
704 | |||
647 | #ifdef DEBUG_EXT | 705 | #ifdef DEBUG_EXT |
648 | printk(KERN_INFO "Loading up ext 0x%lx\n", msr); | 706 | printk(KERN_INFO "Loading up ext 0x%lx\n", msr); |
649 | #endif | 707 | #endif |
@@ -720,6 +778,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
720 | * that no guest that needs the dcbz hack does NX. | 778 | * that no guest that needs the dcbz hack does NX. |
721 | */ | 779 | */ |
722 | kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL); | 780 | kvmppc_mmu_pte_flush(vcpu, vcpu->arch.pc, ~0xFFFULL); |
781 | r = RESUME_GUEST; | ||
723 | } else { | 782 | } else { |
724 | vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000; | 783 | vcpu->arch.msr |= vcpu->arch.shadow_srr1 & 0x58000000; |
725 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); | 784 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); |
@@ -769,6 +828,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
769 | enum emulation_result er; | 828 | enum emulation_result er; |
770 | ulong flags; | 829 | ulong flags; |
771 | 830 | ||
831 | program_interrupt: | ||
772 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; | 832 | flags = vcpu->arch.shadow_srr1 & 0x1f0000ull; |
773 | 833 | ||
774 | if (vcpu->arch.msr & MSR_PR) { | 834 | if (vcpu->arch.msr & MSR_PR) { |
@@ -789,33 +849,80 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
789 | case EMULATE_DONE: | 849 | case EMULATE_DONE: |
790 | r = RESUME_GUEST_NV; | 850 | r = RESUME_GUEST_NV; |
791 | break; | 851 | break; |
852 | case EMULATE_AGAIN: | ||
853 | r = RESUME_GUEST; | ||
854 | break; | ||
792 | case EMULATE_FAIL: | 855 | case EMULATE_FAIL: |
793 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", | 856 | printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n", |
794 | __func__, vcpu->arch.pc, vcpu->arch.last_inst); | 857 | __func__, vcpu->arch.pc, vcpu->arch.last_inst); |
795 | kvmppc_core_queue_program(vcpu, flags); | 858 | kvmppc_core_queue_program(vcpu, flags); |
796 | r = RESUME_GUEST; | 859 | r = RESUME_GUEST; |
797 | break; | 860 | break; |
861 | case EMULATE_DO_MMIO: | ||
862 | run->exit_reason = KVM_EXIT_MMIO; | ||
863 | r = RESUME_HOST_NV; | ||
864 | break; | ||
798 | default: | 865 | default: |
799 | BUG(); | 866 | BUG(); |
800 | } | 867 | } |
801 | break; | 868 | break; |
802 | } | 869 | } |
803 | case BOOK3S_INTERRUPT_SYSCALL: | 870 | case BOOK3S_INTERRUPT_SYSCALL: |
804 | #ifdef EXIT_DEBUG | 871 | // XXX make user settable |
805 | printk(KERN_INFO "Syscall Nr %d\n", (int)kvmppc_get_gpr(vcpu, 0)); | 872 | if (vcpu->arch.osi_enabled && |
806 | #endif | 873 | (((u32)kvmppc_get_gpr(vcpu, 3)) == OSI_SC_MAGIC_R3) && |
807 | vcpu->stat.syscall_exits++; | 874 | (((u32)kvmppc_get_gpr(vcpu, 4)) == OSI_SC_MAGIC_R4)) { |
808 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); | 875 | u64 *gprs = run->osi.gprs; |
809 | r = RESUME_GUEST; | 876 | int i; |
877 | |||
878 | run->exit_reason = KVM_EXIT_OSI; | ||
879 | for (i = 0; i < 32; i++) | ||
880 | gprs[i] = kvmppc_get_gpr(vcpu, i); | ||
881 | vcpu->arch.osi_needed = 1; | ||
882 | r = RESUME_HOST_NV; | ||
883 | |||
884 | } else { | ||
885 | vcpu->stat.syscall_exits++; | ||
886 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); | ||
887 | r = RESUME_GUEST; | ||
888 | } | ||
810 | break; | 889 | break; |
811 | case BOOK3S_INTERRUPT_FP_UNAVAIL: | 890 | case BOOK3S_INTERRUPT_FP_UNAVAIL: |
812 | r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP); | ||
813 | break; | ||
814 | case BOOK3S_INTERRUPT_ALTIVEC: | 891 | case BOOK3S_INTERRUPT_ALTIVEC: |
815 | r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC); | ||
816 | break; | ||
817 | case BOOK3S_INTERRUPT_VSX: | 892 | case BOOK3S_INTERRUPT_VSX: |
818 | r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX); | 893 | { |
894 | int ext_msr = 0; | ||
895 | |||
896 | switch (exit_nr) { | ||
897 | case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break; | ||
898 | case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break; | ||
899 | case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break; | ||
900 | } | ||
901 | |||
902 | switch (kvmppc_check_ext(vcpu, exit_nr)) { | ||
903 | case EMULATE_DONE: | ||
904 | /* everything ok - let's enable the ext */ | ||
905 | r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr); | ||
906 | break; | ||
907 | case EMULATE_FAIL: | ||
908 | /* we need to emulate this instruction */ | ||
909 | goto program_interrupt; | ||
910 | break; | ||
911 | default: | ||
912 | /* nothing to worry about - go again */ | ||
913 | break; | ||
914 | } | ||
915 | break; | ||
916 | } | ||
917 | case BOOK3S_INTERRUPT_ALIGNMENT: | ||
918 | if (kvmppc_read_inst(vcpu) == EMULATE_DONE) { | ||
919 | to_book3s(vcpu)->dsisr = kvmppc_alignment_dsisr(vcpu, | ||
920 | vcpu->arch.last_inst); | ||
921 | vcpu->arch.dear = kvmppc_alignment_dar(vcpu, | ||
922 | vcpu->arch.last_inst); | ||
923 | kvmppc_book3s_queue_irqprio(vcpu, exit_nr); | ||
924 | } | ||
925 | r = RESUME_GUEST; | ||
819 | break; | 926 | break; |
820 | case BOOK3S_INTERRUPT_MACHINE_CHECK: | 927 | case BOOK3S_INTERRUPT_MACHINE_CHECK: |
821 | case BOOK3S_INTERRUPT_TRACE: | 928 | case BOOK3S_INTERRUPT_TRACE: |
@@ -867,6 +974,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
867 | { | 974 | { |
868 | int i; | 975 | int i; |
869 | 976 | ||
977 | vcpu_load(vcpu); | ||
978 | |||
870 | regs->pc = vcpu->arch.pc; | 979 | regs->pc = vcpu->arch.pc; |
871 | regs->cr = kvmppc_get_cr(vcpu); | 980 | regs->cr = kvmppc_get_cr(vcpu); |
872 | regs->ctr = vcpu->arch.ctr; | 981 | regs->ctr = vcpu->arch.ctr; |
@@ -887,6 +996,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
887 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 996 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
888 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); | 997 | regs->gpr[i] = kvmppc_get_gpr(vcpu, i); |
889 | 998 | ||
999 | vcpu_put(vcpu); | ||
1000 | |||
890 | return 0; | 1001 | return 0; |
891 | } | 1002 | } |
892 | 1003 | ||
@@ -894,6 +1005,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
894 | { | 1005 | { |
895 | int i; | 1006 | int i; |
896 | 1007 | ||
1008 | vcpu_load(vcpu); | ||
1009 | |||
897 | vcpu->arch.pc = regs->pc; | 1010 | vcpu->arch.pc = regs->pc; |
898 | kvmppc_set_cr(vcpu, regs->cr); | 1011 | kvmppc_set_cr(vcpu, regs->cr); |
899 | vcpu->arch.ctr = regs->ctr; | 1012 | vcpu->arch.ctr = regs->ctr; |
@@ -913,6 +1026,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
913 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) | 1026 | for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) |
914 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); | 1027 | kvmppc_set_gpr(vcpu, i, regs->gpr[i]); |
915 | 1028 | ||
1029 | vcpu_put(vcpu); | ||
1030 | |||
916 | return 0; | 1031 | return 0; |
917 | } | 1032 | } |
918 | 1033 | ||
@@ -1004,7 +1119,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
1004 | struct kvm_vcpu *vcpu; | 1119 | struct kvm_vcpu *vcpu; |
1005 | ulong ga, ga_end; | 1120 | ulong ga, ga_end; |
1006 | int is_dirty = 0; | 1121 | int is_dirty = 0; |
1007 | int r, n; | 1122 | int r; |
1123 | unsigned long n; | ||
1008 | 1124 | ||
1009 | mutex_lock(&kvm->slots_lock); | 1125 | mutex_lock(&kvm->slots_lock); |
1010 | 1126 | ||
@@ -1022,7 +1138,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
1022 | kvm_for_each_vcpu(n, vcpu, kvm) | 1138 | kvm_for_each_vcpu(n, vcpu, kvm) |
1023 | kvmppc_mmu_pte_pflush(vcpu, ga, ga_end); | 1139 | kvmppc_mmu_pte_pflush(vcpu, ga, ga_end); |
1024 | 1140 | ||
1025 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 1141 | n = kvm_dirty_bitmap_bytes(memslot); |
1026 | memset(memslot->dirty_bitmap, 0, n); | 1142 | memset(memslot->dirty_bitmap, 0, n); |
1027 | } | 1143 | } |
1028 | 1144 | ||
@@ -1043,12 +1159,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
1043 | struct kvm_vcpu *vcpu; | 1159 | struct kvm_vcpu *vcpu; |
1044 | int err; | 1160 | int err; |
1045 | 1161 | ||
1046 | vcpu_book3s = (struct kvmppc_vcpu_book3s *)__get_free_pages( GFP_KERNEL | __GFP_ZERO, | 1162 | vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s)); |
1047 | get_order(sizeof(struct kvmppc_vcpu_book3s))); | ||
1048 | if (!vcpu_book3s) { | 1163 | if (!vcpu_book3s) { |
1049 | err = -ENOMEM; | 1164 | err = -ENOMEM; |
1050 | goto out; | 1165 | goto out; |
1051 | } | 1166 | } |
1167 | memset(vcpu_book3s, 0, sizeof(struct kvmppc_vcpu_book3s)); | ||
1052 | 1168 | ||
1053 | vcpu = &vcpu_book3s->vcpu; | 1169 | vcpu = &vcpu_book3s->vcpu; |
1054 | err = kvm_vcpu_init(vcpu, kvm, id); | 1170 | err = kvm_vcpu_init(vcpu, kvm, id); |
@@ -1082,7 +1198,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
1082 | return vcpu; | 1198 | return vcpu; |
1083 | 1199 | ||
1084 | free_vcpu: | 1200 | free_vcpu: |
1085 | free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s))); | 1201 | vfree(vcpu_book3s); |
1086 | out: | 1202 | out: |
1087 | return ERR_PTR(err); | 1203 | return ERR_PTR(err); |
1088 | } | 1204 | } |
@@ -1093,7 +1209,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | |||
1093 | 1209 | ||
1094 | __destroy_context(vcpu_book3s->context_id); | 1210 | __destroy_context(vcpu_book3s->context_id); |
1095 | kvm_vcpu_uninit(vcpu); | 1211 | kvm_vcpu_uninit(vcpu); |
1096 | free_pages((long)vcpu_book3s, get_order(sizeof(struct kvmppc_vcpu_book3s))); | 1212 | vfree(vcpu_book3s); |
1097 | } | 1213 | } |
1098 | 1214 | ||
1099 | extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 1215 | extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
@@ -1101,8 +1217,12 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1101 | { | 1217 | { |
1102 | int ret; | 1218 | int ret; |
1103 | struct thread_struct ext_bkp; | 1219 | struct thread_struct ext_bkp; |
1220 | #ifdef CONFIG_ALTIVEC | ||
1104 | bool save_vec = current->thread.used_vr; | 1221 | bool save_vec = current->thread.used_vr; |
1222 | #endif | ||
1223 | #ifdef CONFIG_VSX | ||
1105 | bool save_vsx = current->thread.used_vsr; | 1224 | bool save_vsx = current->thread.used_vsr; |
1225 | #endif | ||
1106 | ulong ext_msr; | 1226 | ulong ext_msr; |
1107 | 1227 | ||
1108 | /* No need to go into the guest when all we do is going out */ | 1228 | /* No need to go into the guest when all we do is going out */ |
@@ -1143,6 +1263,10 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1143 | /* XXX we get called with irq disabled - change that! */ | 1263 | /* XXX we get called with irq disabled - change that! */ |
1144 | local_irq_enable(); | 1264 | local_irq_enable(); |
1145 | 1265 | ||
1266 | /* Preload FPU if it's enabled */ | ||
1267 | if (vcpu->arch.msr & MSR_FP) | ||
1268 | kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); | ||
1269 | |||
1146 | ret = __kvmppc_vcpu_entry(kvm_run, vcpu); | 1270 | ret = __kvmppc_vcpu_entry(kvm_run, vcpu); |
1147 | 1271 | ||
1148 | local_irq_disable(); | 1272 | local_irq_disable(); |
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c index faf99f20d993..7071e22b42ff 100644 --- a/arch/powerpc/kvm/book3s_32_mmu.c +++ b/arch/powerpc/kvm/book3s_32_mmu.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #define dprintk(X...) do { } while(0) | 37 | #define dprintk(X...) do { } while(0) |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifdef DEBUG_PTE | 40 | #ifdef DEBUG_MMU_PTE |
41 | #define dprintk_pte(X...) printk(KERN_INFO X) | 41 | #define dprintk_pte(X...) printk(KERN_INFO X) |
42 | #else | 42 | #else |
43 | #define dprintk_pte(X...) do { } while(0) | 43 | #define dprintk_pte(X...) do { } while(0) |
@@ -57,6 +57,8 @@ static inline bool check_debug_ip(struct kvm_vcpu *vcpu) | |||
57 | 57 | ||
58 | static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, | 58 | static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, |
59 | struct kvmppc_pte *pte, bool data); | 59 | struct kvmppc_pte *pte, bool data); |
60 | static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, | ||
61 | u64 *vsid); | ||
60 | 62 | ||
61 | static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr) | 63 | static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t eaddr) |
62 | { | 64 | { |
@@ -66,13 +68,14 @@ static struct kvmppc_sr *find_sr(struct kvmppc_vcpu_book3s *vcpu_book3s, gva_t e | |||
66 | static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, | 68 | static u64 kvmppc_mmu_book3s_32_ea_to_vp(struct kvm_vcpu *vcpu, gva_t eaddr, |
67 | bool data) | 69 | bool data) |
68 | { | 70 | { |
69 | struct kvmppc_sr *sre = find_sr(to_book3s(vcpu), eaddr); | 71 | u64 vsid; |
70 | struct kvmppc_pte pte; | 72 | struct kvmppc_pte pte; |
71 | 73 | ||
72 | if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data)) | 74 | if (!kvmppc_mmu_book3s_32_xlate_bat(vcpu, eaddr, &pte, data)) |
73 | return pte.vpage; | 75 | return pte.vpage; |
74 | 76 | ||
75 | return (((u64)eaddr >> 12) & 0xffff) | (((u64)sre->vsid) << 16); | 77 | kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, eaddr >> SID_SHIFT, &vsid); |
78 | return (((u64)eaddr >> 12) & 0xffff) | (vsid << 16); | ||
76 | } | 79 | } |
77 | 80 | ||
78 | static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu) | 81 | static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu) |
@@ -142,8 +145,13 @@ static int kvmppc_mmu_book3s_32_xlate_bat(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
142 | bat->bepi_mask); | 145 | bat->bepi_mask); |
143 | } | 146 | } |
144 | if ((eaddr & bat->bepi_mask) == bat->bepi) { | 147 | if ((eaddr & bat->bepi_mask) == bat->bepi) { |
148 | u64 vsid; | ||
149 | kvmppc_mmu_book3s_32_esid_to_vsid(vcpu, | ||
150 | eaddr >> SID_SHIFT, &vsid); | ||
151 | vsid <<= 16; | ||
152 | pte->vpage = (((u64)eaddr >> 12) & 0xffff) | vsid; | ||
153 | |||
145 | pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask); | 154 | pte->raddr = bat->brpn | (eaddr & ~bat->bepi_mask); |
146 | pte->vpage = (eaddr >> 12) | VSID_BAT; | ||
147 | pte->may_read = bat->pp; | 155 | pte->may_read = bat->pp; |
148 | pte->may_write = bat->pp > 1; | 156 | pte->may_write = bat->pp > 1; |
149 | pte->may_execute = true; | 157 | pte->may_execute = true; |
@@ -302,6 +310,7 @@ static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, | |||
302 | /* And then put in the new SR */ | 310 | /* And then put in the new SR */ |
303 | sre->raw = value; | 311 | sre->raw = value; |
304 | sre->vsid = (value & 0x0fffffff); | 312 | sre->vsid = (value & 0x0fffffff); |
313 | sre->valid = (value & 0x80000000) ? false : true; | ||
305 | sre->Ks = (value & 0x40000000) ? true : false; | 314 | sre->Ks = (value & 0x40000000) ? true : false; |
306 | sre->Kp = (value & 0x20000000) ? true : false; | 315 | sre->Kp = (value & 0x20000000) ? true : false; |
307 | sre->nx = (value & 0x10000000) ? true : false; | 316 | sre->nx = (value & 0x10000000) ? true : false; |
@@ -312,7 +321,7 @@ static void kvmppc_mmu_book3s_32_mtsrin(struct kvm_vcpu *vcpu, u32 srnum, | |||
312 | 321 | ||
313 | static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large) | 322 | static void kvmppc_mmu_book3s_32_tlbie(struct kvm_vcpu *vcpu, ulong ea, bool large) |
314 | { | 323 | { |
315 | kvmppc_mmu_pte_flush(vcpu, ea, ~0xFFFULL); | 324 | kvmppc_mmu_pte_flush(vcpu, ea, 0x0FFFF000); |
316 | } | 325 | } |
317 | 326 | ||
318 | static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, | 327 | static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, |
@@ -333,15 +342,22 @@ static int kvmppc_mmu_book3s_32_esid_to_vsid(struct kvm_vcpu *vcpu, u64 esid, | |||
333 | break; | 342 | break; |
334 | case MSR_DR|MSR_IR: | 343 | case MSR_DR|MSR_IR: |
335 | { | 344 | { |
336 | ulong ea; | 345 | ulong ea = esid << SID_SHIFT; |
337 | ea = esid << SID_SHIFT; | 346 | struct kvmppc_sr *sr = find_sr(to_book3s(vcpu), ea); |
338 | *vsid = find_sr(to_book3s(vcpu), ea)->vsid; | 347 | |
348 | if (!sr->valid) | ||
349 | return -1; | ||
350 | |||
351 | *vsid = sr->vsid; | ||
339 | break; | 352 | break; |
340 | } | 353 | } |
341 | default: | 354 | default: |
342 | BUG(); | 355 | BUG(); |
343 | } | 356 | } |
344 | 357 | ||
358 | if (vcpu->arch.msr & MSR_PR) | ||
359 | *vsid |= VSID_PR; | ||
360 | |||
345 | return 0; | 361 | return 0; |
346 | } | 362 | } |
347 | 363 | ||
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c index 2b0ee7e040c9..8f50776a9a1d 100644 --- a/arch/powerpc/kvm/book3s_64_emulate.c +++ b/arch/powerpc/kvm/book3s_64_emulate.c | |||
@@ -28,13 +28,16 @@ | |||
28 | #define OP_31_XOP_MFMSR 83 | 28 | #define OP_31_XOP_MFMSR 83 |
29 | #define OP_31_XOP_MTMSR 146 | 29 | #define OP_31_XOP_MTMSR 146 |
30 | #define OP_31_XOP_MTMSRD 178 | 30 | #define OP_31_XOP_MTMSRD 178 |
31 | #define OP_31_XOP_MTSR 210 | ||
31 | #define OP_31_XOP_MTSRIN 242 | 32 | #define OP_31_XOP_MTSRIN 242 |
32 | #define OP_31_XOP_TLBIEL 274 | 33 | #define OP_31_XOP_TLBIEL 274 |
33 | #define OP_31_XOP_TLBIE 306 | 34 | #define OP_31_XOP_TLBIE 306 |
34 | #define OP_31_XOP_SLBMTE 402 | 35 | #define OP_31_XOP_SLBMTE 402 |
35 | #define OP_31_XOP_SLBIE 434 | 36 | #define OP_31_XOP_SLBIE 434 |
36 | #define OP_31_XOP_SLBIA 498 | 37 | #define OP_31_XOP_SLBIA 498 |
38 | #define OP_31_XOP_MFSR 595 | ||
37 | #define OP_31_XOP_MFSRIN 659 | 39 | #define OP_31_XOP_MFSRIN 659 |
40 | #define OP_31_XOP_DCBA 758 | ||
38 | #define OP_31_XOP_SLBMFEV 851 | 41 | #define OP_31_XOP_SLBMFEV 851 |
39 | #define OP_31_XOP_EIOIO 854 | 42 | #define OP_31_XOP_EIOIO 854 |
40 | #define OP_31_XOP_SLBMFEE 915 | 43 | #define OP_31_XOP_SLBMFEE 915 |
@@ -42,6 +45,20 @@ | |||
42 | /* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ | 45 | /* DCBZ is actually 1014, but we patch it to 1010 so we get a trap */ |
43 | #define OP_31_XOP_DCBZ 1010 | 46 | #define OP_31_XOP_DCBZ 1010 |
44 | 47 | ||
48 | #define OP_LFS 48 | ||
49 | #define OP_LFD 50 | ||
50 | #define OP_STFS 52 | ||
51 | #define OP_STFD 54 | ||
52 | |||
53 | #define SPRN_GQR0 912 | ||
54 | #define SPRN_GQR1 913 | ||
55 | #define SPRN_GQR2 914 | ||
56 | #define SPRN_GQR3 915 | ||
57 | #define SPRN_GQR4 916 | ||
58 | #define SPRN_GQR5 917 | ||
59 | #define SPRN_GQR6 918 | ||
60 | #define SPRN_GQR7 919 | ||
61 | |||
45 | int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | 62 | int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, |
46 | unsigned int inst, int *advance) | 63 | unsigned int inst, int *advance) |
47 | { | 64 | { |
@@ -80,6 +97,18 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
80 | case OP_31_XOP_MTMSR: | 97 | case OP_31_XOP_MTMSR: |
81 | kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); | 98 | kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); |
82 | break; | 99 | break; |
100 | case OP_31_XOP_MFSR: | ||
101 | { | ||
102 | int srnum; | ||
103 | |||
104 | srnum = kvmppc_get_field(inst, 12 + 32, 15 + 32); | ||
105 | if (vcpu->arch.mmu.mfsrin) { | ||
106 | u32 sr; | ||
107 | sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); | ||
108 | kvmppc_set_gpr(vcpu, get_rt(inst), sr); | ||
109 | } | ||
110 | break; | ||
111 | } | ||
83 | case OP_31_XOP_MFSRIN: | 112 | case OP_31_XOP_MFSRIN: |
84 | { | 113 | { |
85 | int srnum; | 114 | int srnum; |
@@ -92,6 +121,11 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
92 | } | 121 | } |
93 | break; | 122 | break; |
94 | } | 123 | } |
124 | case OP_31_XOP_MTSR: | ||
125 | vcpu->arch.mmu.mtsrin(vcpu, | ||
126 | (inst >> 16) & 0xf, | ||
127 | kvmppc_get_gpr(vcpu, get_rs(inst))); | ||
128 | break; | ||
95 | case OP_31_XOP_MTSRIN: | 129 | case OP_31_XOP_MTSRIN: |
96 | vcpu->arch.mmu.mtsrin(vcpu, | 130 | vcpu->arch.mmu.mtsrin(vcpu, |
97 | (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, | 131 | (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, |
@@ -150,12 +184,17 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
150 | kvmppc_set_gpr(vcpu, get_rt(inst), t); | 184 | kvmppc_set_gpr(vcpu, get_rt(inst), t); |
151 | } | 185 | } |
152 | break; | 186 | break; |
187 | case OP_31_XOP_DCBA: | ||
188 | /* Gets treated as NOP */ | ||
189 | break; | ||
153 | case OP_31_XOP_DCBZ: | 190 | case OP_31_XOP_DCBZ: |
154 | { | 191 | { |
155 | ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); | 192 | ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); |
156 | ulong ra = 0; | 193 | ulong ra = 0; |
157 | ulong addr; | 194 | ulong addr, vaddr; |
158 | u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 195 | u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
196 | u32 dsisr; | ||
197 | int r; | ||
159 | 198 | ||
160 | if (get_ra(inst)) | 199 | if (get_ra(inst)) |
161 | ra = kvmppc_get_gpr(vcpu, get_ra(inst)); | 200 | ra = kvmppc_get_gpr(vcpu, get_ra(inst)); |
@@ -163,15 +202,25 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
163 | addr = (ra + rb) & ~31ULL; | 202 | addr = (ra + rb) & ~31ULL; |
164 | if (!(vcpu->arch.msr & MSR_SF)) | 203 | if (!(vcpu->arch.msr & MSR_SF)) |
165 | addr &= 0xffffffff; | 204 | addr &= 0xffffffff; |
205 | vaddr = addr; | ||
206 | |||
207 | r = kvmppc_st(vcpu, &addr, 32, zeros, true); | ||
208 | if ((r == -ENOENT) || (r == -EPERM)) { | ||
209 | *advance = 0; | ||
210 | vcpu->arch.dear = vaddr; | ||
211 | vcpu->arch.fault_dear = vaddr; | ||
212 | |||
213 | dsisr = DSISR_ISSTORE; | ||
214 | if (r == -ENOENT) | ||
215 | dsisr |= DSISR_NOHPTE; | ||
216 | else if (r == -EPERM) | ||
217 | dsisr |= DSISR_PROTFAULT; | ||
218 | |||
219 | to_book3s(vcpu)->dsisr = dsisr; | ||
220 | vcpu->arch.fault_dsisr = dsisr; | ||
166 | 221 | ||
167 | if (kvmppc_st(vcpu, addr, 32, zeros)) { | ||
168 | vcpu->arch.dear = addr; | ||
169 | vcpu->arch.fault_dear = addr; | ||
170 | to_book3s(vcpu)->dsisr = DSISR_PROTFAULT | | ||
171 | DSISR_ISSTORE; | ||
172 | kvmppc_book3s_queue_irqprio(vcpu, | 222 | kvmppc_book3s_queue_irqprio(vcpu, |
173 | BOOK3S_INTERRUPT_DATA_STORAGE); | 223 | BOOK3S_INTERRUPT_DATA_STORAGE); |
174 | kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL); | ||
175 | } | 224 | } |
176 | 225 | ||
177 | break; | 226 | break; |
@@ -184,6 +233,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
184 | emulated = EMULATE_FAIL; | 233 | emulated = EMULATE_FAIL; |
185 | } | 234 | } |
186 | 235 | ||
236 | if (emulated == EMULATE_FAIL) | ||
237 | emulated = kvmppc_emulate_paired_single(run, vcpu); | ||
238 | |||
187 | return emulated; | 239 | return emulated; |
188 | } | 240 | } |
189 | 241 | ||
@@ -207,6 +259,34 @@ void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, | |||
207 | } | 259 | } |
208 | } | 260 | } |
209 | 261 | ||
262 | static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) | ||
263 | { | ||
264 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); | ||
265 | struct kvmppc_bat *bat; | ||
266 | |||
267 | switch (sprn) { | ||
268 | case SPRN_IBAT0U ... SPRN_IBAT3L: | ||
269 | bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; | ||
270 | break; | ||
271 | case SPRN_IBAT4U ... SPRN_IBAT7L: | ||
272 | bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; | ||
273 | break; | ||
274 | case SPRN_DBAT0U ... SPRN_DBAT3L: | ||
275 | bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; | ||
276 | break; | ||
277 | case SPRN_DBAT4U ... SPRN_DBAT7L: | ||
278 | bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; | ||
279 | break; | ||
280 | default: | ||
281 | BUG(); | ||
282 | } | ||
283 | |||
284 | if (sprn % 2) | ||
285 | return bat->raw >> 32; | ||
286 | else | ||
287 | return bat->raw; | ||
288 | } | ||
289 | |||
210 | static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) | 290 | static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) |
211 | { | 291 | { |
212 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); | 292 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); |
@@ -217,13 +297,13 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) | |||
217 | bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; | 297 | bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; |
218 | break; | 298 | break; |
219 | case SPRN_IBAT4U ... SPRN_IBAT7L: | 299 | case SPRN_IBAT4U ... SPRN_IBAT7L: |
220 | bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT4U) / 2]; | 300 | bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; |
221 | break; | 301 | break; |
222 | case SPRN_DBAT0U ... SPRN_DBAT3L: | 302 | case SPRN_DBAT0U ... SPRN_DBAT3L: |
223 | bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; | 303 | bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; |
224 | break; | 304 | break; |
225 | case SPRN_DBAT4U ... SPRN_DBAT7L: | 305 | case SPRN_DBAT4U ... SPRN_DBAT7L: |
226 | bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT4U) / 2]; | 306 | bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; |
227 | break; | 307 | break; |
228 | default: | 308 | default: |
229 | BUG(); | 309 | BUG(); |
@@ -258,6 +338,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
258 | /* BAT writes happen so rarely that we're ok to flush | 338 | /* BAT writes happen so rarely that we're ok to flush |
259 | * everything here */ | 339 | * everything here */ |
260 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | 340 | kvmppc_mmu_pte_flush(vcpu, 0, 0); |
341 | kvmppc_mmu_flush_segments(vcpu); | ||
261 | break; | 342 | break; |
262 | case SPRN_HID0: | 343 | case SPRN_HID0: |
263 | to_book3s(vcpu)->hid[0] = spr_val; | 344 | to_book3s(vcpu)->hid[0] = spr_val; |
@@ -268,7 +349,29 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
268 | case SPRN_HID2: | 349 | case SPRN_HID2: |
269 | to_book3s(vcpu)->hid[2] = spr_val; | 350 | to_book3s(vcpu)->hid[2] = spr_val; |
270 | break; | 351 | break; |
352 | case SPRN_HID2_GEKKO: | ||
353 | to_book3s(vcpu)->hid[2] = spr_val; | ||
354 | /* HID2.PSE controls paired single on gekko */ | ||
355 | switch (vcpu->arch.pvr) { | ||
356 | case 0x00080200: /* lonestar 2.0 */ | ||
357 | case 0x00088202: /* lonestar 2.2 */ | ||
358 | case 0x70000100: /* gekko 1.0 */ | ||
359 | case 0x00080100: /* gekko 2.0 */ | ||
360 | case 0x00083203: /* gekko 2.3a */ | ||
361 | case 0x00083213: /* gekko 2.3b */ | ||
362 | case 0x00083204: /* gekko 2.4 */ | ||
363 | case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ | ||
364 | if (spr_val & (1 << 29)) { /* HID2.PSE */ | ||
365 | vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; | ||
366 | kvmppc_giveup_ext(vcpu, MSR_FP); | ||
367 | } else { | ||
368 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_PAIRED_SINGLE; | ||
369 | } | ||
370 | break; | ||
371 | } | ||
372 | break; | ||
271 | case SPRN_HID4: | 373 | case SPRN_HID4: |
374 | case SPRN_HID4_GEKKO: | ||
272 | to_book3s(vcpu)->hid[4] = spr_val; | 375 | to_book3s(vcpu)->hid[4] = spr_val; |
273 | break; | 376 | break; |
274 | case SPRN_HID5: | 377 | case SPRN_HID5: |
@@ -278,12 +381,30 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
278 | (mfmsr() & MSR_HV)) | 381 | (mfmsr() & MSR_HV)) |
279 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; | 382 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; |
280 | break; | 383 | break; |
384 | case SPRN_GQR0: | ||
385 | case SPRN_GQR1: | ||
386 | case SPRN_GQR2: | ||
387 | case SPRN_GQR3: | ||
388 | case SPRN_GQR4: | ||
389 | case SPRN_GQR5: | ||
390 | case SPRN_GQR6: | ||
391 | case SPRN_GQR7: | ||
392 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0] = spr_val; | ||
393 | break; | ||
281 | case SPRN_ICTC: | 394 | case SPRN_ICTC: |
282 | case SPRN_THRM1: | 395 | case SPRN_THRM1: |
283 | case SPRN_THRM2: | 396 | case SPRN_THRM2: |
284 | case SPRN_THRM3: | 397 | case SPRN_THRM3: |
285 | case SPRN_CTRLF: | 398 | case SPRN_CTRLF: |
286 | case SPRN_CTRLT: | 399 | case SPRN_CTRLT: |
400 | case SPRN_L2CR: | ||
401 | case SPRN_MMCR0_GEKKO: | ||
402 | case SPRN_MMCR1_GEKKO: | ||
403 | case SPRN_PMC1_GEKKO: | ||
404 | case SPRN_PMC2_GEKKO: | ||
405 | case SPRN_PMC3_GEKKO: | ||
406 | case SPRN_PMC4_GEKKO: | ||
407 | case SPRN_WPAR_GEKKO: | ||
287 | break; | 408 | break; |
288 | default: | 409 | default: |
289 | printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn); | 410 | printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn); |
@@ -301,6 +422,12 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
301 | int emulated = EMULATE_DONE; | 422 | int emulated = EMULATE_DONE; |
302 | 423 | ||
303 | switch (sprn) { | 424 | switch (sprn) { |
425 | case SPRN_IBAT0U ... SPRN_IBAT3L: | ||
426 | case SPRN_IBAT4U ... SPRN_IBAT7L: | ||
427 | case SPRN_DBAT0U ... SPRN_DBAT3L: | ||
428 | case SPRN_DBAT4U ... SPRN_DBAT7L: | ||
429 | kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn)); | ||
430 | break; | ||
304 | case SPRN_SDR1: | 431 | case SPRN_SDR1: |
305 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); | 432 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); |
306 | break; | 433 | break; |
@@ -320,19 +447,40 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
320 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); | 447 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); |
321 | break; | 448 | break; |
322 | case SPRN_HID2: | 449 | case SPRN_HID2: |
450 | case SPRN_HID2_GEKKO: | ||
323 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); | 451 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); |
324 | break; | 452 | break; |
325 | case SPRN_HID4: | 453 | case SPRN_HID4: |
454 | case SPRN_HID4_GEKKO: | ||
326 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); | 455 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); |
327 | break; | 456 | break; |
328 | case SPRN_HID5: | 457 | case SPRN_HID5: |
329 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); | 458 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); |
330 | break; | 459 | break; |
460 | case SPRN_GQR0: | ||
461 | case SPRN_GQR1: | ||
462 | case SPRN_GQR2: | ||
463 | case SPRN_GQR3: | ||
464 | case SPRN_GQR4: | ||
465 | case SPRN_GQR5: | ||
466 | case SPRN_GQR6: | ||
467 | case SPRN_GQR7: | ||
468 | kvmppc_set_gpr(vcpu, rt, | ||
469 | to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]); | ||
470 | break; | ||
331 | case SPRN_THRM1: | 471 | case SPRN_THRM1: |
332 | case SPRN_THRM2: | 472 | case SPRN_THRM2: |
333 | case SPRN_THRM3: | 473 | case SPRN_THRM3: |
334 | case SPRN_CTRLF: | 474 | case SPRN_CTRLF: |
335 | case SPRN_CTRLT: | 475 | case SPRN_CTRLT: |
476 | case SPRN_L2CR: | ||
477 | case SPRN_MMCR0_GEKKO: | ||
478 | case SPRN_MMCR1_GEKKO: | ||
479 | case SPRN_PMC1_GEKKO: | ||
480 | case SPRN_PMC2_GEKKO: | ||
481 | case SPRN_PMC3_GEKKO: | ||
482 | case SPRN_PMC4_GEKKO: | ||
483 | case SPRN_WPAR_GEKKO: | ||
336 | kvmppc_set_gpr(vcpu, rt, 0); | 484 | kvmppc_set_gpr(vcpu, rt, 0); |
337 | break; | 485 | break; |
338 | default: | 486 | default: |
@@ -346,3 +494,73 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
346 | return emulated; | 494 | return emulated; |
347 | } | 495 | } |
348 | 496 | ||
497 | u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst) | ||
498 | { | ||
499 | u32 dsisr = 0; | ||
500 | |||
501 | /* | ||
502 | * This is what the spec says about DSISR bits (not mentioned = 0): | ||
503 | * | ||
504 | * 12:13 [DS] Set to bits 30:31 | ||
505 | * 15:16 [X] Set to bits 29:30 | ||
506 | * 17 [X] Set to bit 25 | ||
507 | * [D/DS] Set to bit 5 | ||
508 | * 18:21 [X] Set to bits 21:24 | ||
509 | * [D/DS] Set to bits 1:4 | ||
510 | * 22:26 Set to bits 6:10 (RT/RS/FRT/FRS) | ||
511 | * 27:31 Set to bits 11:15 (RA) | ||
512 | */ | ||
513 | |||
514 | switch (get_op(inst)) { | ||
515 | /* D-form */ | ||
516 | case OP_LFS: | ||
517 | case OP_LFD: | ||
518 | case OP_STFD: | ||
519 | case OP_STFS: | ||
520 | dsisr |= (inst >> 12) & 0x4000; /* bit 17 */ | ||
521 | dsisr |= (inst >> 17) & 0x3c00; /* bits 18:21 */ | ||
522 | break; | ||
523 | /* X-form */ | ||
524 | case 31: | ||
525 | dsisr |= (inst << 14) & 0x18000; /* bits 15:16 */ | ||
526 | dsisr |= (inst << 8) & 0x04000; /* bit 17 */ | ||
527 | dsisr |= (inst << 3) & 0x03c00; /* bits 18:21 */ | ||
528 | break; | ||
529 | default: | ||
530 | printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | dsisr |= (inst >> 16) & 0x03ff; /* bits 22:31 */ | ||
535 | |||
536 | return dsisr; | ||
537 | } | ||
538 | |||
539 | ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst) | ||
540 | { | ||
541 | ulong dar = 0; | ||
542 | ulong ra; | ||
543 | |||
544 | switch (get_op(inst)) { | ||
545 | case OP_LFS: | ||
546 | case OP_LFD: | ||
547 | case OP_STFD: | ||
548 | case OP_STFS: | ||
549 | ra = get_ra(inst); | ||
550 | if (ra) | ||
551 | dar = kvmppc_get_gpr(vcpu, ra); | ||
552 | dar += (s32)((s16)inst); | ||
553 | break; | ||
554 | case 31: | ||
555 | ra = get_ra(inst); | ||
556 | if (ra) | ||
557 | dar = kvmppc_get_gpr(vcpu, ra); | ||
558 | dar += kvmppc_get_gpr(vcpu, get_rb(inst)); | ||
559 | break; | ||
560 | default: | ||
561 | printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | return dar; | ||
566 | } | ||
diff --git a/arch/powerpc/kvm/book3s_64_interrupts.S b/arch/powerpc/kvm/book3s_64_interrupts.S index c1584d0cbce8..faca87610d65 100644 --- a/arch/powerpc/kvm/book3s_64_interrupts.S +++ b/arch/powerpc/kvm/book3s_64_interrupts.S | |||
@@ -171,7 +171,7 @@ kvmppc_handler_highmem: | |||
171 | std r3, VCPU_PC(r7) | 171 | std r3, VCPU_PC(r7) |
172 | std r4, VCPU_SHADOW_SRR1(r7) | 172 | std r4, VCPU_SHADOW_SRR1(r7) |
173 | std r5, VCPU_FAULT_DEAR(r7) | 173 | std r5, VCPU_FAULT_DEAR(r7) |
174 | std r6, VCPU_FAULT_DSISR(r7) | 174 | stw r6, VCPU_FAULT_DSISR(r7) |
175 | 175 | ||
176 | ld r5, VCPU_HFLAGS(r7) | 176 | ld r5, VCPU_HFLAGS(r7) |
177 | rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ | 177 | rldicl. r5, r5, 0, 63 /* CR = ((r5 & 1) == 0) */ |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index f2899b297ffd..a01e9c5a3fc7 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c | |||
@@ -257,16 +257,9 @@ map_again: | |||
257 | 257 | ||
258 | if (ret < 0) { | 258 | if (ret < 0) { |
259 | /* If we couldn't map a primary PTE, try a secondary */ | 259 | /* If we couldn't map a primary PTE, try a secondary */ |
260 | #ifdef USE_SECONDARY | ||
261 | hash = ~hash; | 260 | hash = ~hash; |
261 | vflags ^= HPTE_V_SECONDARY; | ||
262 | attempt++; | 262 | attempt++; |
263 | if (attempt % 2) | ||
264 | vflags = HPTE_V_SECONDARY; | ||
265 | else | ||
266 | vflags = 0; | ||
267 | #else | ||
268 | attempt = 2; | ||
269 | #endif | ||
270 | goto map_again; | 263 | goto map_again; |
271 | } else { | 264 | } else { |
272 | int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); | 265 | int hpte_id = kvmppc_mmu_hpte_cache_next(vcpu); |
@@ -277,6 +270,13 @@ map_again: | |||
277 | (rflags & HPTE_R_N) ? '-' : 'x', | 270 | (rflags & HPTE_R_N) ? '-' : 'x', |
278 | orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr); | 271 | orig_pte->eaddr, hpteg, va, orig_pte->vpage, hpaddr); |
279 | 272 | ||
273 | /* The ppc_md code may give us a secondary entry even though we | ||
274 | asked for a primary. Fix up. */ | ||
275 | if ((ret & _PTEIDX_SECONDARY) && !(vflags & HPTE_V_SECONDARY)) { | ||
276 | hash = ~hash; | ||
277 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | ||
278 | } | ||
279 | |||
280 | pte->slot = hpteg + (ret & 7); | 280 | pte->slot = hpteg + (ret & 7); |
281 | pte->host_va = va; | 281 | pte->host_va = va; |
282 | pte->pte = *orig_pte; | 282 | pte->pte = *orig_pte; |
diff --git a/arch/powerpc/kvm/book3s_64_rmhandlers.S b/arch/powerpc/kvm/book3s_64_rmhandlers.S index c83c60ad96c5..bd08535fcdc8 100644 --- a/arch/powerpc/kvm/book3s_64_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_64_rmhandlers.S | |||
@@ -164,24 +164,15 @@ _GLOBAL(kvmppc_rmcall) | |||
164 | #define define_load_up(what) \ | 164 | #define define_load_up(what) \ |
165 | \ | 165 | \ |
166 | _GLOBAL(kvmppc_load_up_ ## what); \ | 166 | _GLOBAL(kvmppc_load_up_ ## what); \ |
167 | subi r1, r1, INT_FRAME_SIZE; \ | 167 | stdu r1, -INT_FRAME_SIZE(r1); \ |
168 | mflr r3; \ | 168 | mflr r3; \ |
169 | std r3, _LINK(r1); \ | 169 | std r3, _LINK(r1); \ |
170 | mfmsr r4; \ | ||
171 | std r31, GPR3(r1); \ | ||
172 | mr r31, r4; \ | ||
173 | li r5, MSR_DR; \ | ||
174 | oris r5, r5, MSR_EE@h; \ | ||
175 | andc r4, r4, r5; \ | ||
176 | mtmsr r4; \ | ||
177 | \ | 170 | \ |
178 | bl .load_up_ ## what; \ | 171 | bl .load_up_ ## what; \ |
179 | \ | 172 | \ |
180 | mtmsr r31; \ | ||
181 | ld r3, _LINK(r1); \ | 173 | ld r3, _LINK(r1); \ |
182 | ld r31, GPR3(r1); \ | ||
183 | addi r1, r1, INT_FRAME_SIZE; \ | ||
184 | mtlr r3; \ | 174 | mtlr r3; \ |
175 | addi r1, r1, INT_FRAME_SIZE; \ | ||
185 | blr | 176 | blr |
186 | 177 | ||
187 | define_load_up(fpu) | 178 | define_load_up(fpu) |
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S index 35b762722187..091967907954 100644 --- a/arch/powerpc/kvm/book3s_64_slb.S +++ b/arch/powerpc/kvm/book3s_64_slb.S | |||
@@ -145,7 +145,7 @@ slb_do_enter: | |||
145 | lwz r11, (PACA_KVM_CR)(r13) | 145 | lwz r11, (PACA_KVM_CR)(r13) |
146 | mtcr r11 | 146 | mtcr r11 |
147 | 147 | ||
148 | ld r11, (PACA_KVM_XER)(r13) | 148 | lwz r11, (PACA_KVM_XER)(r13) |
149 | mtxer r11 | 149 | mtxer r11 |
150 | 150 | ||
151 | ld r11, (PACA_KVM_R11)(r13) | 151 | ld r11, (PACA_KVM_R11)(r13) |
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c new file mode 100644 index 000000000000..7a27bac8c44a --- /dev/null +++ b/arch/powerpc/kvm/book3s_paired_singles.c | |||
@@ -0,0 +1,1289 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License, version 2, as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
14 | * | ||
15 | * Copyright Novell Inc 2010 | ||
16 | * | ||
17 | * Authors: Alexander Graf <agraf@suse.de> | ||
18 | */ | ||
19 | |||
20 | #include <asm/kvm.h> | ||
21 | #include <asm/kvm_ppc.h> | ||
22 | #include <asm/disassemble.h> | ||
23 | #include <asm/kvm_book3s.h> | ||
24 | #include <asm/kvm_fpu.h> | ||
25 | #include <asm/reg.h> | ||
26 | #include <asm/cacheflush.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | |||
29 | /* #define DEBUG */ | ||
30 | |||
31 | #ifdef DEBUG | ||
32 | #define dprintk printk | ||
33 | #else | ||
34 | #define dprintk(...) do { } while(0); | ||
35 | #endif | ||
36 | |||
37 | #define OP_LFS 48 | ||
38 | #define OP_LFSU 49 | ||
39 | #define OP_LFD 50 | ||
40 | #define OP_LFDU 51 | ||
41 | #define OP_STFS 52 | ||
42 | #define OP_STFSU 53 | ||
43 | #define OP_STFD 54 | ||
44 | #define OP_STFDU 55 | ||
45 | #define OP_PSQ_L 56 | ||
46 | #define OP_PSQ_LU 57 | ||
47 | #define OP_PSQ_ST 60 | ||
48 | #define OP_PSQ_STU 61 | ||
49 | |||
50 | #define OP_31_LFSX 535 | ||
51 | #define OP_31_LFSUX 567 | ||
52 | #define OP_31_LFDX 599 | ||
53 | #define OP_31_LFDUX 631 | ||
54 | #define OP_31_STFSX 663 | ||
55 | #define OP_31_STFSUX 695 | ||
56 | #define OP_31_STFX 727 | ||
57 | #define OP_31_STFUX 759 | ||
58 | #define OP_31_LWIZX 887 | ||
59 | #define OP_31_STFIWX 983 | ||
60 | |||
61 | #define OP_59_FADDS 21 | ||
62 | #define OP_59_FSUBS 20 | ||
63 | #define OP_59_FSQRTS 22 | ||
64 | #define OP_59_FDIVS 18 | ||
65 | #define OP_59_FRES 24 | ||
66 | #define OP_59_FMULS 25 | ||
67 | #define OP_59_FRSQRTES 26 | ||
68 | #define OP_59_FMSUBS 28 | ||
69 | #define OP_59_FMADDS 29 | ||
70 | #define OP_59_FNMSUBS 30 | ||
71 | #define OP_59_FNMADDS 31 | ||
72 | |||
73 | #define OP_63_FCMPU 0 | ||
74 | #define OP_63_FCPSGN 8 | ||
75 | #define OP_63_FRSP 12 | ||
76 | #define OP_63_FCTIW 14 | ||
77 | #define OP_63_FCTIWZ 15 | ||
78 | #define OP_63_FDIV 18 | ||
79 | #define OP_63_FADD 21 | ||
80 | #define OP_63_FSQRT 22 | ||
81 | #define OP_63_FSEL 23 | ||
82 | #define OP_63_FRE 24 | ||
83 | #define OP_63_FMUL 25 | ||
84 | #define OP_63_FRSQRTE 26 | ||
85 | #define OP_63_FMSUB 28 | ||
86 | #define OP_63_FMADD 29 | ||
87 | #define OP_63_FNMSUB 30 | ||
88 | #define OP_63_FNMADD 31 | ||
89 | #define OP_63_FCMPO 32 | ||
90 | #define OP_63_MTFSB1 38 // XXX | ||
91 | #define OP_63_FSUB 20 | ||
92 | #define OP_63_FNEG 40 | ||
93 | #define OP_63_MCRFS 64 | ||
94 | #define OP_63_MTFSB0 70 | ||
95 | #define OP_63_FMR 72 | ||
96 | #define OP_63_MTFSFI 134 | ||
97 | #define OP_63_FABS 264 | ||
98 | #define OP_63_MFFS 583 | ||
99 | #define OP_63_MTFSF 711 | ||
100 | |||
101 | #define OP_4X_PS_CMPU0 0 | ||
102 | #define OP_4X_PSQ_LX 6 | ||
103 | #define OP_4XW_PSQ_STX 7 | ||
104 | #define OP_4A_PS_SUM0 10 | ||
105 | #define OP_4A_PS_SUM1 11 | ||
106 | #define OP_4A_PS_MULS0 12 | ||
107 | #define OP_4A_PS_MULS1 13 | ||
108 | #define OP_4A_PS_MADDS0 14 | ||
109 | #define OP_4A_PS_MADDS1 15 | ||
110 | #define OP_4A_PS_DIV 18 | ||
111 | #define OP_4A_PS_SUB 20 | ||
112 | #define OP_4A_PS_ADD 21 | ||
113 | #define OP_4A_PS_SEL 23 | ||
114 | #define OP_4A_PS_RES 24 | ||
115 | #define OP_4A_PS_MUL 25 | ||
116 | #define OP_4A_PS_RSQRTE 26 | ||
117 | #define OP_4A_PS_MSUB 28 | ||
118 | #define OP_4A_PS_MADD 29 | ||
119 | #define OP_4A_PS_NMSUB 30 | ||
120 | #define OP_4A_PS_NMADD 31 | ||
121 | #define OP_4X_PS_CMPO0 32 | ||
122 | #define OP_4X_PSQ_LUX 38 | ||
123 | #define OP_4XW_PSQ_STUX 39 | ||
124 | #define OP_4X_PS_NEG 40 | ||
125 | #define OP_4X_PS_CMPU1 64 | ||
126 | #define OP_4X_PS_MR 72 | ||
127 | #define OP_4X_PS_CMPO1 96 | ||
128 | #define OP_4X_PS_NABS 136 | ||
129 | #define OP_4X_PS_ABS 264 | ||
130 | #define OP_4X_PS_MERGE00 528 | ||
131 | #define OP_4X_PS_MERGE01 560 | ||
132 | #define OP_4X_PS_MERGE10 592 | ||
133 | #define OP_4X_PS_MERGE11 624 | ||
134 | |||
135 | #define SCALAR_NONE 0 | ||
136 | #define SCALAR_HIGH (1 << 0) | ||
137 | #define SCALAR_LOW (1 << 1) | ||
138 | #define SCALAR_NO_PS0 (1 << 2) | ||
139 | #define SCALAR_NO_PS1 (1 << 3) | ||
140 | |||
141 | #define GQR_ST_TYPE_MASK 0x00000007 | ||
142 | #define GQR_ST_TYPE_SHIFT 0 | ||
143 | #define GQR_ST_SCALE_MASK 0x00003f00 | ||
144 | #define GQR_ST_SCALE_SHIFT 8 | ||
145 | #define GQR_LD_TYPE_MASK 0x00070000 | ||
146 | #define GQR_LD_TYPE_SHIFT 16 | ||
147 | #define GQR_LD_SCALE_MASK 0x3f000000 | ||
148 | #define GQR_LD_SCALE_SHIFT 24 | ||
149 | |||
150 | #define GQR_QUANTIZE_FLOAT 0 | ||
151 | #define GQR_QUANTIZE_U8 4 | ||
152 | #define GQR_QUANTIZE_U16 5 | ||
153 | #define GQR_QUANTIZE_S8 6 | ||
154 | #define GQR_QUANTIZE_S16 7 | ||
155 | |||
156 | #define FPU_LS_SINGLE 0 | ||
157 | #define FPU_LS_DOUBLE 1 | ||
158 | #define FPU_LS_SINGLE_LOW 2 | ||
159 | |||
160 | static inline void kvmppc_sync_qpr(struct kvm_vcpu *vcpu, int rt) | ||
161 | { | ||
162 | struct thread_struct t; | ||
163 | |||
164 | t.fpscr.val = vcpu->arch.fpscr; | ||
165 | cvt_df((double*)&vcpu->arch.fpr[rt], (float*)&vcpu->arch.qpr[rt], &t); | ||
166 | } | ||
167 | |||
168 | static void kvmppc_inject_pf(struct kvm_vcpu *vcpu, ulong eaddr, bool is_store) | ||
169 | { | ||
170 | u64 dsisr; | ||
171 | |||
172 | vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 36, 0); | ||
173 | vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0); | ||
174 | vcpu->arch.dear = eaddr; | ||
175 | /* Page Fault */ | ||
176 | dsisr = kvmppc_set_field(0, 33, 33, 1); | ||
177 | if (is_store) | ||
178 | to_book3s(vcpu)->dsisr = kvmppc_set_field(dsisr, 38, 38, 1); | ||
179 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE); | ||
180 | } | ||
181 | |||
182 | static int kvmppc_emulate_fpr_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
183 | int rs, ulong addr, int ls_type) | ||
184 | { | ||
185 | int emulated = EMULATE_FAIL; | ||
186 | struct thread_struct t; | ||
187 | int r; | ||
188 | char tmp[8]; | ||
189 | int len = sizeof(u32); | ||
190 | |||
191 | if (ls_type == FPU_LS_DOUBLE) | ||
192 | len = sizeof(u64); | ||
193 | |||
194 | t.fpscr.val = vcpu->arch.fpscr; | ||
195 | |||
196 | /* read from memory */ | ||
197 | r = kvmppc_ld(vcpu, &addr, len, tmp, true); | ||
198 | vcpu->arch.paddr_accessed = addr; | ||
199 | |||
200 | if (r < 0) { | ||
201 | kvmppc_inject_pf(vcpu, addr, false); | ||
202 | goto done_load; | ||
203 | } else if (r == EMULATE_DO_MMIO) { | ||
204 | emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FPR | rs, len, 1); | ||
205 | goto done_load; | ||
206 | } | ||
207 | |||
208 | emulated = EMULATE_DONE; | ||
209 | |||
210 | /* put in registers */ | ||
211 | switch (ls_type) { | ||
212 | case FPU_LS_SINGLE: | ||
213 | cvt_fd((float*)tmp, (double*)&vcpu->arch.fpr[rs], &t); | ||
214 | vcpu->arch.qpr[rs] = *((u32*)tmp); | ||
215 | break; | ||
216 | case FPU_LS_DOUBLE: | ||
217 | vcpu->arch.fpr[rs] = *((u64*)tmp); | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | dprintk(KERN_INFO "KVM: FPR_LD [0x%llx] at 0x%lx (%d)\n", *(u64*)tmp, | ||
222 | addr, len); | ||
223 | |||
224 | done_load: | ||
225 | return emulated; | ||
226 | } | ||
227 | |||
228 | static int kvmppc_emulate_fpr_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
229 | int rs, ulong addr, int ls_type) | ||
230 | { | ||
231 | int emulated = EMULATE_FAIL; | ||
232 | struct thread_struct t; | ||
233 | int r; | ||
234 | char tmp[8]; | ||
235 | u64 val; | ||
236 | int len; | ||
237 | |||
238 | t.fpscr.val = vcpu->arch.fpscr; | ||
239 | |||
240 | switch (ls_type) { | ||
241 | case FPU_LS_SINGLE: | ||
242 | cvt_df((double*)&vcpu->arch.fpr[rs], (float*)tmp, &t); | ||
243 | val = *((u32*)tmp); | ||
244 | len = sizeof(u32); | ||
245 | break; | ||
246 | case FPU_LS_SINGLE_LOW: | ||
247 | *((u32*)tmp) = vcpu->arch.fpr[rs]; | ||
248 | val = vcpu->arch.fpr[rs] & 0xffffffff; | ||
249 | len = sizeof(u32); | ||
250 | break; | ||
251 | case FPU_LS_DOUBLE: | ||
252 | *((u64*)tmp) = vcpu->arch.fpr[rs]; | ||
253 | val = vcpu->arch.fpr[rs]; | ||
254 | len = sizeof(u64); | ||
255 | break; | ||
256 | default: | ||
257 | val = 0; | ||
258 | len = 0; | ||
259 | } | ||
260 | |||
261 | r = kvmppc_st(vcpu, &addr, len, tmp, true); | ||
262 | vcpu->arch.paddr_accessed = addr; | ||
263 | if (r < 0) { | ||
264 | kvmppc_inject_pf(vcpu, addr, true); | ||
265 | } else if (r == EMULATE_DO_MMIO) { | ||
266 | emulated = kvmppc_handle_store(run, vcpu, val, len, 1); | ||
267 | } else { | ||
268 | emulated = EMULATE_DONE; | ||
269 | } | ||
270 | |||
271 | dprintk(KERN_INFO "KVM: FPR_ST [0x%llx] at 0x%lx (%d)\n", | ||
272 | val, addr, len); | ||
273 | |||
274 | return emulated; | ||
275 | } | ||
276 | |||
277 | static int kvmppc_emulate_psq_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
278 | int rs, ulong addr, bool w, int i) | ||
279 | { | ||
280 | int emulated = EMULATE_FAIL; | ||
281 | struct thread_struct t; | ||
282 | int r; | ||
283 | float one = 1.0; | ||
284 | u32 tmp[2]; | ||
285 | |||
286 | t.fpscr.val = vcpu->arch.fpscr; | ||
287 | |||
288 | /* read from memory */ | ||
289 | if (w) { | ||
290 | r = kvmppc_ld(vcpu, &addr, sizeof(u32), tmp, true); | ||
291 | memcpy(&tmp[1], &one, sizeof(u32)); | ||
292 | } else { | ||
293 | r = kvmppc_ld(vcpu, &addr, sizeof(u32) * 2, tmp, true); | ||
294 | } | ||
295 | vcpu->arch.paddr_accessed = addr; | ||
296 | if (r < 0) { | ||
297 | kvmppc_inject_pf(vcpu, addr, false); | ||
298 | goto done_load; | ||
299 | } else if ((r == EMULATE_DO_MMIO) && w) { | ||
300 | emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FPR | rs, 4, 1); | ||
301 | vcpu->arch.qpr[rs] = tmp[1]; | ||
302 | goto done_load; | ||
303 | } else if (r == EMULATE_DO_MMIO) { | ||
304 | emulated = kvmppc_handle_load(run, vcpu, KVM_REG_FQPR | rs, 8, 1); | ||
305 | goto done_load; | ||
306 | } | ||
307 | |||
308 | emulated = EMULATE_DONE; | ||
309 | |||
310 | /* put in registers */ | ||
311 | cvt_fd((float*)&tmp[0], (double*)&vcpu->arch.fpr[rs], &t); | ||
312 | vcpu->arch.qpr[rs] = tmp[1]; | ||
313 | |||
314 | dprintk(KERN_INFO "KVM: PSQ_LD [0x%x, 0x%x] at 0x%lx (%d)\n", tmp[0], | ||
315 | tmp[1], addr, w ? 4 : 8); | ||
316 | |||
317 | done_load: | ||
318 | return emulated; | ||
319 | } | ||
320 | |||
321 | static int kvmppc_emulate_psq_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
322 | int rs, ulong addr, bool w, int i) | ||
323 | { | ||
324 | int emulated = EMULATE_FAIL; | ||
325 | struct thread_struct t; | ||
326 | int r; | ||
327 | u32 tmp[2]; | ||
328 | int len = w ? sizeof(u32) : sizeof(u64); | ||
329 | |||
330 | t.fpscr.val = vcpu->arch.fpscr; | ||
331 | |||
332 | cvt_df((double*)&vcpu->arch.fpr[rs], (float*)&tmp[0], &t); | ||
333 | tmp[1] = vcpu->arch.qpr[rs]; | ||
334 | |||
335 | r = kvmppc_st(vcpu, &addr, len, tmp, true); | ||
336 | vcpu->arch.paddr_accessed = addr; | ||
337 | if (r < 0) { | ||
338 | kvmppc_inject_pf(vcpu, addr, true); | ||
339 | } else if ((r == EMULATE_DO_MMIO) && w) { | ||
340 | emulated = kvmppc_handle_store(run, vcpu, tmp[0], 4, 1); | ||
341 | } else if (r == EMULATE_DO_MMIO) { | ||
342 | u64 val = ((u64)tmp[0] << 32) | tmp[1]; | ||
343 | emulated = kvmppc_handle_store(run, vcpu, val, 8, 1); | ||
344 | } else { | ||
345 | emulated = EMULATE_DONE; | ||
346 | } | ||
347 | |||
348 | dprintk(KERN_INFO "KVM: PSQ_ST [0x%x, 0x%x] at 0x%lx (%d)\n", | ||
349 | tmp[0], tmp[1], addr, len); | ||
350 | |||
351 | return emulated; | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * Cuts out inst bits with ordering according to spec. | ||
356 | * That means the leftmost bit is zero. All given bits are included. | ||
357 | */ | ||
358 | static inline u32 inst_get_field(u32 inst, int msb, int lsb) | ||
359 | { | ||
360 | return kvmppc_get_field(inst, msb + 32, lsb + 32); | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * Replaces inst bits with ordering according to spec. | ||
365 | */ | ||
366 | static inline u32 inst_set_field(u32 inst, int msb, int lsb, int value) | ||
367 | { | ||
368 | return kvmppc_set_field(inst, msb + 32, lsb + 32, value); | ||
369 | } | ||
370 | |||
371 | bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) | ||
372 | { | ||
373 | if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE)) | ||
374 | return false; | ||
375 | |||
376 | switch (get_op(inst)) { | ||
377 | case OP_PSQ_L: | ||
378 | case OP_PSQ_LU: | ||
379 | case OP_PSQ_ST: | ||
380 | case OP_PSQ_STU: | ||
381 | case OP_LFS: | ||
382 | case OP_LFSU: | ||
383 | case OP_LFD: | ||
384 | case OP_LFDU: | ||
385 | case OP_STFS: | ||
386 | case OP_STFSU: | ||
387 | case OP_STFD: | ||
388 | case OP_STFDU: | ||
389 | return true; | ||
390 | case 4: | ||
391 | /* X form */ | ||
392 | switch (inst_get_field(inst, 21, 30)) { | ||
393 | case OP_4X_PS_CMPU0: | ||
394 | case OP_4X_PSQ_LX: | ||
395 | case OP_4X_PS_CMPO0: | ||
396 | case OP_4X_PSQ_LUX: | ||
397 | case OP_4X_PS_NEG: | ||
398 | case OP_4X_PS_CMPU1: | ||
399 | case OP_4X_PS_MR: | ||
400 | case OP_4X_PS_CMPO1: | ||
401 | case OP_4X_PS_NABS: | ||
402 | case OP_4X_PS_ABS: | ||
403 | case OP_4X_PS_MERGE00: | ||
404 | case OP_4X_PS_MERGE01: | ||
405 | case OP_4X_PS_MERGE10: | ||
406 | case OP_4X_PS_MERGE11: | ||
407 | return true; | ||
408 | } | ||
409 | /* XW form */ | ||
410 | switch (inst_get_field(inst, 25, 30)) { | ||
411 | case OP_4XW_PSQ_STX: | ||
412 | case OP_4XW_PSQ_STUX: | ||
413 | return true; | ||
414 | } | ||
415 | /* A form */ | ||
416 | switch (inst_get_field(inst, 26, 30)) { | ||
417 | case OP_4A_PS_SUM1: | ||
418 | case OP_4A_PS_SUM0: | ||
419 | case OP_4A_PS_MULS0: | ||
420 | case OP_4A_PS_MULS1: | ||
421 | case OP_4A_PS_MADDS0: | ||
422 | case OP_4A_PS_MADDS1: | ||
423 | case OP_4A_PS_DIV: | ||
424 | case OP_4A_PS_SUB: | ||
425 | case OP_4A_PS_ADD: | ||
426 | case OP_4A_PS_SEL: | ||
427 | case OP_4A_PS_RES: | ||
428 | case OP_4A_PS_MUL: | ||
429 | case OP_4A_PS_RSQRTE: | ||
430 | case OP_4A_PS_MSUB: | ||
431 | case OP_4A_PS_MADD: | ||
432 | case OP_4A_PS_NMSUB: | ||
433 | case OP_4A_PS_NMADD: | ||
434 | return true; | ||
435 | } | ||
436 | break; | ||
437 | case 59: | ||
438 | switch (inst_get_field(inst, 21, 30)) { | ||
439 | case OP_59_FADDS: | ||
440 | case OP_59_FSUBS: | ||
441 | case OP_59_FDIVS: | ||
442 | case OP_59_FRES: | ||
443 | case OP_59_FRSQRTES: | ||
444 | return true; | ||
445 | } | ||
446 | switch (inst_get_field(inst, 26, 30)) { | ||
447 | case OP_59_FMULS: | ||
448 | case OP_59_FMSUBS: | ||
449 | case OP_59_FMADDS: | ||
450 | case OP_59_FNMSUBS: | ||
451 | case OP_59_FNMADDS: | ||
452 | return true; | ||
453 | } | ||
454 | break; | ||
455 | case 63: | ||
456 | switch (inst_get_field(inst, 21, 30)) { | ||
457 | case OP_63_MTFSB0: | ||
458 | case OP_63_MTFSB1: | ||
459 | case OP_63_MTFSF: | ||
460 | case OP_63_MTFSFI: | ||
461 | case OP_63_MCRFS: | ||
462 | case OP_63_MFFS: | ||
463 | case OP_63_FCMPU: | ||
464 | case OP_63_FCMPO: | ||
465 | case OP_63_FNEG: | ||
466 | case OP_63_FMR: | ||
467 | case OP_63_FABS: | ||
468 | case OP_63_FRSP: | ||
469 | case OP_63_FDIV: | ||
470 | case OP_63_FADD: | ||
471 | case OP_63_FSUB: | ||
472 | case OP_63_FCTIW: | ||
473 | case OP_63_FCTIWZ: | ||
474 | case OP_63_FRSQRTE: | ||
475 | case OP_63_FCPSGN: | ||
476 | return true; | ||
477 | } | ||
478 | switch (inst_get_field(inst, 26, 30)) { | ||
479 | case OP_63_FMUL: | ||
480 | case OP_63_FSEL: | ||
481 | case OP_63_FMSUB: | ||
482 | case OP_63_FMADD: | ||
483 | case OP_63_FNMSUB: | ||
484 | case OP_63_FNMADD: | ||
485 | return true; | ||
486 | } | ||
487 | break; | ||
488 | case 31: | ||
489 | switch (inst_get_field(inst, 21, 30)) { | ||
490 | case OP_31_LFSX: | ||
491 | case OP_31_LFSUX: | ||
492 | case OP_31_LFDX: | ||
493 | case OP_31_LFDUX: | ||
494 | case OP_31_STFSX: | ||
495 | case OP_31_STFSUX: | ||
496 | case OP_31_STFX: | ||
497 | case OP_31_STFUX: | ||
498 | case OP_31_STFIWX: | ||
499 | return true; | ||
500 | } | ||
501 | break; | ||
502 | } | ||
503 | |||
504 | return false; | ||
505 | } | ||
506 | |||
507 | static int get_d_signext(u32 inst) | ||
508 | { | ||
509 | int d = inst & 0x8ff; | ||
510 | |||
511 | if (d & 0x800) | ||
512 | return -(d & 0x7ff); | ||
513 | |||
514 | return (d & 0x7ff); | ||
515 | } | ||
516 | |||
517 | static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc, | ||
518 | int reg_out, int reg_in1, int reg_in2, | ||
519 | int reg_in3, int scalar, | ||
520 | void (*func)(struct thread_struct *t, | ||
521 | u32 *dst, u32 *src1, | ||
522 | u32 *src2, u32 *src3)) | ||
523 | { | ||
524 | u32 *qpr = vcpu->arch.qpr; | ||
525 | u64 *fpr = vcpu->arch.fpr; | ||
526 | u32 ps0_out; | ||
527 | u32 ps0_in1, ps0_in2, ps0_in3; | ||
528 | u32 ps1_in1, ps1_in2, ps1_in3; | ||
529 | struct thread_struct t; | ||
530 | t.fpscr.val = vcpu->arch.fpscr; | ||
531 | |||
532 | /* RC */ | ||
533 | WARN_ON(rc); | ||
534 | |||
535 | /* PS0 */ | ||
536 | cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); | ||
537 | cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); | ||
538 | cvt_df((double*)&fpr[reg_in3], (float*)&ps0_in3, &t); | ||
539 | |||
540 | if (scalar & SCALAR_LOW) | ||
541 | ps0_in2 = qpr[reg_in2]; | ||
542 | |||
543 | func(&t, &ps0_out, &ps0_in1, &ps0_in2, &ps0_in3); | ||
544 | |||
545 | dprintk(KERN_INFO "PS3 ps0 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", | ||
546 | ps0_in1, ps0_in2, ps0_in3, ps0_out); | ||
547 | |||
548 | if (!(scalar & SCALAR_NO_PS0)) | ||
549 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | ||
550 | |||
551 | /* PS1 */ | ||
552 | ps1_in1 = qpr[reg_in1]; | ||
553 | ps1_in2 = qpr[reg_in2]; | ||
554 | ps1_in3 = qpr[reg_in3]; | ||
555 | |||
556 | if (scalar & SCALAR_HIGH) | ||
557 | ps1_in2 = ps0_in2; | ||
558 | |||
559 | if (!(scalar & SCALAR_NO_PS1)) | ||
560 | func(&t, &qpr[reg_out], &ps1_in1, &ps1_in2, &ps1_in3); | ||
561 | |||
562 | dprintk(KERN_INFO "PS3 ps1 -> f(0x%x, 0x%x, 0x%x) = 0x%x\n", | ||
563 | ps1_in1, ps1_in2, ps1_in3, qpr[reg_out]); | ||
564 | |||
565 | return EMULATE_DONE; | ||
566 | } | ||
567 | |||
568 | static int kvmppc_ps_two_in(struct kvm_vcpu *vcpu, bool rc, | ||
569 | int reg_out, int reg_in1, int reg_in2, | ||
570 | int scalar, | ||
571 | void (*func)(struct thread_struct *t, | ||
572 | u32 *dst, u32 *src1, | ||
573 | u32 *src2)) | ||
574 | { | ||
575 | u32 *qpr = vcpu->arch.qpr; | ||
576 | u64 *fpr = vcpu->arch.fpr; | ||
577 | u32 ps0_out; | ||
578 | u32 ps0_in1, ps0_in2; | ||
579 | u32 ps1_out; | ||
580 | u32 ps1_in1, ps1_in2; | ||
581 | struct thread_struct t; | ||
582 | t.fpscr.val = vcpu->arch.fpscr; | ||
583 | |||
584 | /* RC */ | ||
585 | WARN_ON(rc); | ||
586 | |||
587 | /* PS0 */ | ||
588 | cvt_df((double*)&fpr[reg_in1], (float*)&ps0_in1, &t); | ||
589 | |||
590 | if (scalar & SCALAR_LOW) | ||
591 | ps0_in2 = qpr[reg_in2]; | ||
592 | else | ||
593 | cvt_df((double*)&fpr[reg_in2], (float*)&ps0_in2, &t); | ||
594 | |||
595 | func(&t, &ps0_out, &ps0_in1, &ps0_in2); | ||
596 | |||
597 | if (!(scalar & SCALAR_NO_PS0)) { | ||
598 | dprintk(KERN_INFO "PS2 ps0 -> f(0x%x, 0x%x) = 0x%x\n", | ||
599 | ps0_in1, ps0_in2, ps0_out); | ||
600 | |||
601 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | ||
602 | } | ||
603 | |||
604 | /* PS1 */ | ||
605 | ps1_in1 = qpr[reg_in1]; | ||
606 | ps1_in2 = qpr[reg_in2]; | ||
607 | |||
608 | if (scalar & SCALAR_HIGH) | ||
609 | ps1_in2 = ps0_in2; | ||
610 | |||
611 | func(&t, &ps1_out, &ps1_in1, &ps1_in2); | ||
612 | |||
613 | if (!(scalar & SCALAR_NO_PS1)) { | ||
614 | qpr[reg_out] = ps1_out; | ||
615 | |||
616 | dprintk(KERN_INFO "PS2 ps1 -> f(0x%x, 0x%x) = 0x%x\n", | ||
617 | ps1_in1, ps1_in2, qpr[reg_out]); | ||
618 | } | ||
619 | |||
620 | return EMULATE_DONE; | ||
621 | } | ||
622 | |||
623 | static int kvmppc_ps_one_in(struct kvm_vcpu *vcpu, bool rc, | ||
624 | int reg_out, int reg_in, | ||
625 | void (*func)(struct thread_struct *t, | ||
626 | u32 *dst, u32 *src1)) | ||
627 | { | ||
628 | u32 *qpr = vcpu->arch.qpr; | ||
629 | u64 *fpr = vcpu->arch.fpr; | ||
630 | u32 ps0_out, ps0_in; | ||
631 | u32 ps1_in; | ||
632 | struct thread_struct t; | ||
633 | t.fpscr.val = vcpu->arch.fpscr; | ||
634 | |||
635 | /* RC */ | ||
636 | WARN_ON(rc); | ||
637 | |||
638 | /* PS0 */ | ||
639 | cvt_df((double*)&fpr[reg_in], (float*)&ps0_in, &t); | ||
640 | func(&t, &ps0_out, &ps0_in); | ||
641 | |||
642 | dprintk(KERN_INFO "PS1 ps0 -> f(0x%x) = 0x%x\n", | ||
643 | ps0_in, ps0_out); | ||
644 | |||
645 | cvt_fd((float*)&ps0_out, (double*)&fpr[reg_out], &t); | ||
646 | |||
647 | /* PS1 */ | ||
648 | ps1_in = qpr[reg_in]; | ||
649 | func(&t, &qpr[reg_out], &ps1_in); | ||
650 | |||
651 | dprintk(KERN_INFO "PS1 ps1 -> f(0x%x) = 0x%x\n", | ||
652 | ps1_in, qpr[reg_out]); | ||
653 | |||
654 | return EMULATE_DONE; | ||
655 | } | ||
656 | |||
657 | int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu) | ||
658 | { | ||
659 | u32 inst = vcpu->arch.last_inst; | ||
660 | enum emulation_result emulated = EMULATE_DONE; | ||
661 | |||
662 | int ax_rd = inst_get_field(inst, 6, 10); | ||
663 | int ax_ra = inst_get_field(inst, 11, 15); | ||
664 | int ax_rb = inst_get_field(inst, 16, 20); | ||
665 | int ax_rc = inst_get_field(inst, 21, 25); | ||
666 | short full_d = inst_get_field(inst, 16, 31); | ||
667 | |||
668 | u64 *fpr_d = &vcpu->arch.fpr[ax_rd]; | ||
669 | u64 *fpr_a = &vcpu->arch.fpr[ax_ra]; | ||
670 | u64 *fpr_b = &vcpu->arch.fpr[ax_rb]; | ||
671 | u64 *fpr_c = &vcpu->arch.fpr[ax_rc]; | ||
672 | |||
673 | bool rcomp = (inst & 1) ? true : false; | ||
674 | u32 cr = kvmppc_get_cr(vcpu); | ||
675 | struct thread_struct t; | ||
676 | #ifdef DEBUG | ||
677 | int i; | ||
678 | #endif | ||
679 | |||
680 | t.fpscr.val = vcpu->arch.fpscr; | ||
681 | |||
682 | if (!kvmppc_inst_is_paired_single(vcpu, inst)) | ||
683 | return EMULATE_FAIL; | ||
684 | |||
685 | if (!(vcpu->arch.msr & MSR_FP)) { | ||
686 | kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL); | ||
687 | return EMULATE_AGAIN; | ||
688 | } | ||
689 | |||
690 | kvmppc_giveup_ext(vcpu, MSR_FP); | ||
691 | preempt_disable(); | ||
692 | enable_kernel_fp(); | ||
693 | /* Do we need to clear FE0 / FE1 here? Don't think so. */ | ||
694 | |||
695 | #ifdef DEBUG | ||
696 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { | ||
697 | u32 f; | ||
698 | cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); | ||
699 | dprintk(KERN_INFO "FPR[%d] = 0x%x / 0x%llx QPR[%d] = 0x%x\n", | ||
700 | i, f, vcpu->arch.fpr[i], i, vcpu->arch.qpr[i]); | ||
701 | } | ||
702 | #endif | ||
703 | |||
704 | switch (get_op(inst)) { | ||
705 | case OP_PSQ_L: | ||
706 | { | ||
707 | ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; | ||
708 | bool w = inst_get_field(inst, 16, 16) ? true : false; | ||
709 | int i = inst_get_field(inst, 17, 19); | ||
710 | |||
711 | addr += get_d_signext(inst); | ||
712 | emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); | ||
713 | break; | ||
714 | } | ||
715 | case OP_PSQ_LU: | ||
716 | { | ||
717 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra); | ||
718 | bool w = inst_get_field(inst, 16, 16) ? true : false; | ||
719 | int i = inst_get_field(inst, 17, 19); | ||
720 | |||
721 | addr += get_d_signext(inst); | ||
722 | emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); | ||
723 | |||
724 | if (emulated == EMULATE_DONE) | ||
725 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
726 | break; | ||
727 | } | ||
728 | case OP_PSQ_ST: | ||
729 | { | ||
730 | ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; | ||
731 | bool w = inst_get_field(inst, 16, 16) ? true : false; | ||
732 | int i = inst_get_field(inst, 17, 19); | ||
733 | |||
734 | addr += get_d_signext(inst); | ||
735 | emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); | ||
736 | break; | ||
737 | } | ||
738 | case OP_PSQ_STU: | ||
739 | { | ||
740 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra); | ||
741 | bool w = inst_get_field(inst, 16, 16) ? true : false; | ||
742 | int i = inst_get_field(inst, 17, 19); | ||
743 | |||
744 | addr += get_d_signext(inst); | ||
745 | emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); | ||
746 | |||
747 | if (emulated == EMULATE_DONE) | ||
748 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
749 | break; | ||
750 | } | ||
751 | case 4: | ||
752 | /* X form */ | ||
753 | switch (inst_get_field(inst, 21, 30)) { | ||
754 | case OP_4X_PS_CMPU0: | ||
755 | /* XXX */ | ||
756 | emulated = EMULATE_FAIL; | ||
757 | break; | ||
758 | case OP_4X_PSQ_LX: | ||
759 | { | ||
760 | ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; | ||
761 | bool w = inst_get_field(inst, 21, 21) ? true : false; | ||
762 | int i = inst_get_field(inst, 22, 24); | ||
763 | |||
764 | addr += kvmppc_get_gpr(vcpu, ax_rb); | ||
765 | emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); | ||
766 | break; | ||
767 | } | ||
768 | case OP_4X_PS_CMPO0: | ||
769 | /* XXX */ | ||
770 | emulated = EMULATE_FAIL; | ||
771 | break; | ||
772 | case OP_4X_PSQ_LUX: | ||
773 | { | ||
774 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra); | ||
775 | bool w = inst_get_field(inst, 21, 21) ? true : false; | ||
776 | int i = inst_get_field(inst, 22, 24); | ||
777 | |||
778 | addr += kvmppc_get_gpr(vcpu, ax_rb); | ||
779 | emulated = kvmppc_emulate_psq_load(run, vcpu, ax_rd, addr, w, i); | ||
780 | |||
781 | if (emulated == EMULATE_DONE) | ||
782 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
783 | break; | ||
784 | } | ||
785 | case OP_4X_PS_NEG: | ||
786 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; | ||
787 | vcpu->arch.fpr[ax_rd] ^= 0x8000000000000000ULL; | ||
788 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
789 | vcpu->arch.qpr[ax_rd] ^= 0x80000000; | ||
790 | break; | ||
791 | case OP_4X_PS_CMPU1: | ||
792 | /* XXX */ | ||
793 | emulated = EMULATE_FAIL; | ||
794 | break; | ||
795 | case OP_4X_PS_MR: | ||
796 | WARN_ON(rcomp); | ||
797 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; | ||
798 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
799 | break; | ||
800 | case OP_4X_PS_CMPO1: | ||
801 | /* XXX */ | ||
802 | emulated = EMULATE_FAIL; | ||
803 | break; | ||
804 | case OP_4X_PS_NABS: | ||
805 | WARN_ON(rcomp); | ||
806 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; | ||
807 | vcpu->arch.fpr[ax_rd] |= 0x8000000000000000ULL; | ||
808 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
809 | vcpu->arch.qpr[ax_rd] |= 0x80000000; | ||
810 | break; | ||
811 | case OP_4X_PS_ABS: | ||
812 | WARN_ON(rcomp); | ||
813 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rb]; | ||
814 | vcpu->arch.fpr[ax_rd] &= ~0x8000000000000000ULL; | ||
815 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
816 | vcpu->arch.qpr[ax_rd] &= ~0x80000000; | ||
817 | break; | ||
818 | case OP_4X_PS_MERGE00: | ||
819 | WARN_ON(rcomp); | ||
820 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; | ||
821 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ | ||
822 | cvt_df((double*)&vcpu->arch.fpr[ax_rb], | ||
823 | (float*)&vcpu->arch.qpr[ax_rd], &t); | ||
824 | break; | ||
825 | case OP_4X_PS_MERGE01: | ||
826 | WARN_ON(rcomp); | ||
827 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_ra]; | ||
828 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
829 | break; | ||
830 | case OP_4X_PS_MERGE10: | ||
831 | WARN_ON(rcomp); | ||
832 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ | ||
833 | cvt_fd((float*)&vcpu->arch.qpr[ax_ra], | ||
834 | (double*)&vcpu->arch.fpr[ax_rd], &t); | ||
835 | /* vcpu->arch.qpr[ax_rd] = vcpu->arch.fpr[ax_rb]; */ | ||
836 | cvt_df((double*)&vcpu->arch.fpr[ax_rb], | ||
837 | (float*)&vcpu->arch.qpr[ax_rd], &t); | ||
838 | break; | ||
839 | case OP_4X_PS_MERGE11: | ||
840 | WARN_ON(rcomp); | ||
841 | /* vcpu->arch.fpr[ax_rd] = vcpu->arch.qpr[ax_ra]; */ | ||
842 | cvt_fd((float*)&vcpu->arch.qpr[ax_ra], | ||
843 | (double*)&vcpu->arch.fpr[ax_rd], &t); | ||
844 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rb]; | ||
845 | break; | ||
846 | } | ||
847 | /* XW form */ | ||
848 | switch (inst_get_field(inst, 25, 30)) { | ||
849 | case OP_4XW_PSQ_STX: | ||
850 | { | ||
851 | ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; | ||
852 | bool w = inst_get_field(inst, 21, 21) ? true : false; | ||
853 | int i = inst_get_field(inst, 22, 24); | ||
854 | |||
855 | addr += kvmppc_get_gpr(vcpu, ax_rb); | ||
856 | emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); | ||
857 | break; | ||
858 | } | ||
859 | case OP_4XW_PSQ_STUX: | ||
860 | { | ||
861 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra); | ||
862 | bool w = inst_get_field(inst, 21, 21) ? true : false; | ||
863 | int i = inst_get_field(inst, 22, 24); | ||
864 | |||
865 | addr += kvmppc_get_gpr(vcpu, ax_rb); | ||
866 | emulated = kvmppc_emulate_psq_store(run, vcpu, ax_rd, addr, w, i); | ||
867 | |||
868 | if (emulated == EMULATE_DONE) | ||
869 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
870 | break; | ||
871 | } | ||
872 | } | ||
873 | /* A form */ | ||
874 | switch (inst_get_field(inst, 26, 30)) { | ||
875 | case OP_4A_PS_SUM1: | ||
876 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
877 | ax_rb, ax_ra, SCALAR_NO_PS0 | SCALAR_HIGH, fps_fadds); | ||
878 | vcpu->arch.fpr[ax_rd] = vcpu->arch.fpr[ax_rc]; | ||
879 | break; | ||
880 | case OP_4A_PS_SUM0: | ||
881 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
882 | ax_ra, ax_rb, SCALAR_NO_PS1 | SCALAR_LOW, fps_fadds); | ||
883 | vcpu->arch.qpr[ax_rd] = vcpu->arch.qpr[ax_rc]; | ||
884 | break; | ||
885 | case OP_4A_PS_MULS0: | ||
886 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
887 | ax_ra, ax_rc, SCALAR_HIGH, fps_fmuls); | ||
888 | break; | ||
889 | case OP_4A_PS_MULS1: | ||
890 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
891 | ax_ra, ax_rc, SCALAR_LOW, fps_fmuls); | ||
892 | break; | ||
893 | case OP_4A_PS_MADDS0: | ||
894 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
895 | ax_ra, ax_rc, ax_rb, SCALAR_HIGH, fps_fmadds); | ||
896 | break; | ||
897 | case OP_4A_PS_MADDS1: | ||
898 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
899 | ax_ra, ax_rc, ax_rb, SCALAR_LOW, fps_fmadds); | ||
900 | break; | ||
901 | case OP_4A_PS_DIV: | ||
902 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
903 | ax_ra, ax_rb, SCALAR_NONE, fps_fdivs); | ||
904 | break; | ||
905 | case OP_4A_PS_SUB: | ||
906 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
907 | ax_ra, ax_rb, SCALAR_NONE, fps_fsubs); | ||
908 | break; | ||
909 | case OP_4A_PS_ADD: | ||
910 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
911 | ax_ra, ax_rb, SCALAR_NONE, fps_fadds); | ||
912 | break; | ||
913 | case OP_4A_PS_SEL: | ||
914 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
915 | ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fsel); | ||
916 | break; | ||
917 | case OP_4A_PS_RES: | ||
918 | emulated = kvmppc_ps_one_in(vcpu, rcomp, ax_rd, | ||
919 | ax_rb, fps_fres); | ||
920 | break; | ||
921 | case OP_4A_PS_MUL: | ||
922 | emulated = kvmppc_ps_two_in(vcpu, rcomp, ax_rd, | ||
923 | ax_ra, ax_rc, SCALAR_NONE, fps_fmuls); | ||
924 | break; | ||
925 | case OP_4A_PS_RSQRTE: | ||
926 | emulated = kvmppc_ps_one_in(vcpu, rcomp, ax_rd, | ||
927 | ax_rb, fps_frsqrte); | ||
928 | break; | ||
929 | case OP_4A_PS_MSUB: | ||
930 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
931 | ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fmsubs); | ||
932 | break; | ||
933 | case OP_4A_PS_MADD: | ||
934 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
935 | ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fmadds); | ||
936 | break; | ||
937 | case OP_4A_PS_NMSUB: | ||
938 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
939 | ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fnmsubs); | ||
940 | break; | ||
941 | case OP_4A_PS_NMADD: | ||
942 | emulated = kvmppc_ps_three_in(vcpu, rcomp, ax_rd, | ||
943 | ax_ra, ax_rc, ax_rb, SCALAR_NONE, fps_fnmadds); | ||
944 | break; | ||
945 | } | ||
946 | break; | ||
947 | |||
948 | /* Real FPU operations */ | ||
949 | |||
950 | case OP_LFS: | ||
951 | { | ||
952 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; | ||
953 | |||
954 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, | ||
955 | FPU_LS_SINGLE); | ||
956 | break; | ||
957 | } | ||
958 | case OP_LFSU: | ||
959 | { | ||
960 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; | ||
961 | |||
962 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, | ||
963 | FPU_LS_SINGLE); | ||
964 | |||
965 | if (emulated == EMULATE_DONE) | ||
966 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
967 | break; | ||
968 | } | ||
969 | case OP_LFD: | ||
970 | { | ||
971 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; | ||
972 | |||
973 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, | ||
974 | FPU_LS_DOUBLE); | ||
975 | break; | ||
976 | } | ||
977 | case OP_LFDU: | ||
978 | { | ||
979 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; | ||
980 | |||
981 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, addr, | ||
982 | FPU_LS_DOUBLE); | ||
983 | |||
984 | if (emulated == EMULATE_DONE) | ||
985 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
986 | break; | ||
987 | } | ||
988 | case OP_STFS: | ||
989 | { | ||
990 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; | ||
991 | |||
992 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, | ||
993 | FPU_LS_SINGLE); | ||
994 | break; | ||
995 | } | ||
996 | case OP_STFSU: | ||
997 | { | ||
998 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; | ||
999 | |||
1000 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, | ||
1001 | FPU_LS_SINGLE); | ||
1002 | |||
1003 | if (emulated == EMULATE_DONE) | ||
1004 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1005 | break; | ||
1006 | } | ||
1007 | case OP_STFD: | ||
1008 | { | ||
1009 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + full_d; | ||
1010 | |||
1011 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, | ||
1012 | FPU_LS_DOUBLE); | ||
1013 | break; | ||
1014 | } | ||
1015 | case OP_STFDU: | ||
1016 | { | ||
1017 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + full_d; | ||
1018 | |||
1019 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, addr, | ||
1020 | FPU_LS_DOUBLE); | ||
1021 | |||
1022 | if (emulated == EMULATE_DONE) | ||
1023 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1024 | break; | ||
1025 | } | ||
1026 | case 31: | ||
1027 | switch (inst_get_field(inst, 21, 30)) { | ||
1028 | case OP_31_LFSX: | ||
1029 | { | ||
1030 | ulong addr = ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0; | ||
1031 | |||
1032 | addr += kvmppc_get_gpr(vcpu, ax_rb); | ||
1033 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, | ||
1034 | addr, FPU_LS_SINGLE); | ||
1035 | break; | ||
1036 | } | ||
1037 | case OP_31_LFSUX: | ||
1038 | { | ||
1039 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + | ||
1040 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1041 | |||
1042 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, | ||
1043 | addr, FPU_LS_SINGLE); | ||
1044 | |||
1045 | if (emulated == EMULATE_DONE) | ||
1046 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1047 | break; | ||
1048 | } | ||
1049 | case OP_31_LFDX: | ||
1050 | { | ||
1051 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + | ||
1052 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1053 | |||
1054 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, | ||
1055 | addr, FPU_LS_DOUBLE); | ||
1056 | break; | ||
1057 | } | ||
1058 | case OP_31_LFDUX: | ||
1059 | { | ||
1060 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + | ||
1061 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1062 | |||
1063 | emulated = kvmppc_emulate_fpr_load(run, vcpu, ax_rd, | ||
1064 | addr, FPU_LS_DOUBLE); | ||
1065 | |||
1066 | if (emulated == EMULATE_DONE) | ||
1067 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1068 | break; | ||
1069 | } | ||
1070 | case OP_31_STFSX: | ||
1071 | { | ||
1072 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + | ||
1073 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1074 | |||
1075 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, | ||
1076 | addr, FPU_LS_SINGLE); | ||
1077 | break; | ||
1078 | } | ||
1079 | case OP_31_STFSUX: | ||
1080 | { | ||
1081 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + | ||
1082 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1083 | |||
1084 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, | ||
1085 | addr, FPU_LS_SINGLE); | ||
1086 | |||
1087 | if (emulated == EMULATE_DONE) | ||
1088 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1089 | break; | ||
1090 | } | ||
1091 | case OP_31_STFX: | ||
1092 | { | ||
1093 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + | ||
1094 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1095 | |||
1096 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, | ||
1097 | addr, FPU_LS_DOUBLE); | ||
1098 | break; | ||
1099 | } | ||
1100 | case OP_31_STFUX: | ||
1101 | { | ||
1102 | ulong addr = kvmppc_get_gpr(vcpu, ax_ra) + | ||
1103 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1104 | |||
1105 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, | ||
1106 | addr, FPU_LS_DOUBLE); | ||
1107 | |||
1108 | if (emulated == EMULATE_DONE) | ||
1109 | kvmppc_set_gpr(vcpu, ax_ra, addr); | ||
1110 | break; | ||
1111 | } | ||
1112 | case OP_31_STFIWX: | ||
1113 | { | ||
1114 | ulong addr = (ax_ra ? kvmppc_get_gpr(vcpu, ax_ra) : 0) + | ||
1115 | kvmppc_get_gpr(vcpu, ax_rb); | ||
1116 | |||
1117 | emulated = kvmppc_emulate_fpr_store(run, vcpu, ax_rd, | ||
1118 | addr, | ||
1119 | FPU_LS_SINGLE_LOW); | ||
1120 | break; | ||
1121 | } | ||
1122 | break; | ||
1123 | } | ||
1124 | break; | ||
1125 | case 59: | ||
1126 | switch (inst_get_field(inst, 21, 30)) { | ||
1127 | case OP_59_FADDS: | ||
1128 | fpd_fadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1129 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1130 | break; | ||
1131 | case OP_59_FSUBS: | ||
1132 | fpd_fsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1133 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1134 | break; | ||
1135 | case OP_59_FDIVS: | ||
1136 | fpd_fdivs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1137 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1138 | break; | ||
1139 | case OP_59_FRES: | ||
1140 | fpd_fres(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1141 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1142 | break; | ||
1143 | case OP_59_FRSQRTES: | ||
1144 | fpd_frsqrtes(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1145 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1146 | break; | ||
1147 | } | ||
1148 | switch (inst_get_field(inst, 26, 30)) { | ||
1149 | case OP_59_FMULS: | ||
1150 | fpd_fmuls(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c); | ||
1151 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1152 | break; | ||
1153 | case OP_59_FMSUBS: | ||
1154 | fpd_fmsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1155 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1156 | break; | ||
1157 | case OP_59_FMADDS: | ||
1158 | fpd_fmadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1159 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1160 | break; | ||
1161 | case OP_59_FNMSUBS: | ||
1162 | fpd_fnmsubs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1163 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1164 | break; | ||
1165 | case OP_59_FNMADDS: | ||
1166 | fpd_fnmadds(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1167 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1168 | break; | ||
1169 | } | ||
1170 | break; | ||
1171 | case 63: | ||
1172 | switch (inst_get_field(inst, 21, 30)) { | ||
1173 | case OP_63_MTFSB0: | ||
1174 | case OP_63_MTFSB1: | ||
1175 | case OP_63_MCRFS: | ||
1176 | case OP_63_MTFSFI: | ||
1177 | /* XXX need to implement */ | ||
1178 | break; | ||
1179 | case OP_63_MFFS: | ||
1180 | /* XXX missing CR */ | ||
1181 | *fpr_d = vcpu->arch.fpscr; | ||
1182 | break; | ||
1183 | case OP_63_MTFSF: | ||
1184 | /* XXX missing fm bits */ | ||
1185 | /* XXX missing CR */ | ||
1186 | vcpu->arch.fpscr = *fpr_b; | ||
1187 | break; | ||
1188 | case OP_63_FCMPU: | ||
1189 | { | ||
1190 | u32 tmp_cr; | ||
1191 | u32 cr0_mask = 0xf0000000; | ||
1192 | u32 cr_shift = inst_get_field(inst, 6, 8) * 4; | ||
1193 | |||
1194 | fpd_fcmpu(&vcpu->arch.fpscr, &tmp_cr, fpr_a, fpr_b); | ||
1195 | cr &= ~(cr0_mask >> cr_shift); | ||
1196 | cr |= (cr & cr0_mask) >> cr_shift; | ||
1197 | break; | ||
1198 | } | ||
1199 | case OP_63_FCMPO: | ||
1200 | { | ||
1201 | u32 tmp_cr; | ||
1202 | u32 cr0_mask = 0xf0000000; | ||
1203 | u32 cr_shift = inst_get_field(inst, 6, 8) * 4; | ||
1204 | |||
1205 | fpd_fcmpo(&vcpu->arch.fpscr, &tmp_cr, fpr_a, fpr_b); | ||
1206 | cr &= ~(cr0_mask >> cr_shift); | ||
1207 | cr |= (cr & cr0_mask) >> cr_shift; | ||
1208 | break; | ||
1209 | } | ||
1210 | case OP_63_FNEG: | ||
1211 | fpd_fneg(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1212 | break; | ||
1213 | case OP_63_FMR: | ||
1214 | *fpr_d = *fpr_b; | ||
1215 | break; | ||
1216 | case OP_63_FABS: | ||
1217 | fpd_fabs(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1218 | break; | ||
1219 | case OP_63_FCPSGN: | ||
1220 | fpd_fcpsgn(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1221 | break; | ||
1222 | case OP_63_FDIV: | ||
1223 | fpd_fdiv(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1224 | break; | ||
1225 | case OP_63_FADD: | ||
1226 | fpd_fadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1227 | break; | ||
1228 | case OP_63_FSUB: | ||
1229 | fpd_fsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_b); | ||
1230 | break; | ||
1231 | case OP_63_FCTIW: | ||
1232 | fpd_fctiw(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1233 | break; | ||
1234 | case OP_63_FCTIWZ: | ||
1235 | fpd_fctiwz(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1236 | break; | ||
1237 | case OP_63_FRSP: | ||
1238 | fpd_frsp(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1239 | kvmppc_sync_qpr(vcpu, ax_rd); | ||
1240 | break; | ||
1241 | case OP_63_FRSQRTE: | ||
1242 | { | ||
1243 | double one = 1.0f; | ||
1244 | |||
1245 | /* fD = sqrt(fB) */ | ||
1246 | fpd_fsqrt(&vcpu->arch.fpscr, &cr, fpr_d, fpr_b); | ||
1247 | /* fD = 1.0f / fD */ | ||
1248 | fpd_fdiv(&vcpu->arch.fpscr, &cr, fpr_d, (u64*)&one, fpr_d); | ||
1249 | break; | ||
1250 | } | ||
1251 | } | ||
1252 | switch (inst_get_field(inst, 26, 30)) { | ||
1253 | case OP_63_FMUL: | ||
1254 | fpd_fmul(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c); | ||
1255 | break; | ||
1256 | case OP_63_FSEL: | ||
1257 | fpd_fsel(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1258 | break; | ||
1259 | case OP_63_FMSUB: | ||
1260 | fpd_fmsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1261 | break; | ||
1262 | case OP_63_FMADD: | ||
1263 | fpd_fmadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1264 | break; | ||
1265 | case OP_63_FNMSUB: | ||
1266 | fpd_fnmsub(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1267 | break; | ||
1268 | case OP_63_FNMADD: | ||
1269 | fpd_fnmadd(&vcpu->arch.fpscr, &cr, fpr_d, fpr_a, fpr_c, fpr_b); | ||
1270 | break; | ||
1271 | } | ||
1272 | break; | ||
1273 | } | ||
1274 | |||
1275 | #ifdef DEBUG | ||
1276 | for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++) { | ||
1277 | u32 f; | ||
1278 | cvt_df((double*)&vcpu->arch.fpr[i], (float*)&f, &t); | ||
1279 | dprintk(KERN_INFO "FPR[%d] = 0x%x\n", i, f); | ||
1280 | } | ||
1281 | #endif | ||
1282 | |||
1283 | if (rcomp) | ||
1284 | kvmppc_set_cr(vcpu, cr); | ||
1285 | |||
1286 | preempt_enable(); | ||
1287 | |||
1288 | return emulated; | ||
1289 | } | ||
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 2a3a1953d4bd..c92224071021 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -133,6 +133,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | |||
133 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_EXTERNAL); | 133 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_EXTERNAL); |
134 | } | 134 | } |
135 | 135 | ||
136 | void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, | ||
137 | struct kvm_interrupt *irq) | ||
138 | { | ||
139 | clear_bit(BOOKE_IRQPRIO_EXTERNAL, &vcpu->arch.pending_exceptions); | ||
140 | } | ||
141 | |||
136 | /* Deliver the interrupt of the corresponding priority, if possible. */ | 142 | /* Deliver the interrupt of the corresponding priority, if possible. */ |
137 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, | 143 | static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, |
138 | unsigned int priority) | 144 | unsigned int priority) |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index cb72a65f4ecc..dbb5d6842a51 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -38,10 +38,12 @@ | |||
38 | #define OP_31_XOP_LBZX 87 | 38 | #define OP_31_XOP_LBZX 87 |
39 | #define OP_31_XOP_STWX 151 | 39 | #define OP_31_XOP_STWX 151 |
40 | #define OP_31_XOP_STBX 215 | 40 | #define OP_31_XOP_STBX 215 |
41 | #define OP_31_XOP_LBZUX 119 | ||
41 | #define OP_31_XOP_STBUX 247 | 42 | #define OP_31_XOP_STBUX 247 |
42 | #define OP_31_XOP_LHZX 279 | 43 | #define OP_31_XOP_LHZX 279 |
43 | #define OP_31_XOP_LHZUX 311 | 44 | #define OP_31_XOP_LHZUX 311 |
44 | #define OP_31_XOP_MFSPR 339 | 45 | #define OP_31_XOP_MFSPR 339 |
46 | #define OP_31_XOP_LHAX 343 | ||
45 | #define OP_31_XOP_STHX 407 | 47 | #define OP_31_XOP_STHX 407 |
46 | #define OP_31_XOP_STHUX 439 | 48 | #define OP_31_XOP_STHUX 439 |
47 | #define OP_31_XOP_MTSPR 467 | 49 | #define OP_31_XOP_MTSPR 467 |
@@ -62,6 +64,8 @@ | |||
62 | #define OP_STBU 39 | 64 | #define OP_STBU 39 |
63 | #define OP_LHZ 40 | 65 | #define OP_LHZ 40 |
64 | #define OP_LHZU 41 | 66 | #define OP_LHZU 41 |
67 | #define OP_LHA 42 | ||
68 | #define OP_LHAU 43 | ||
65 | #define OP_STH 44 | 69 | #define OP_STH 44 |
66 | #define OP_STHU 45 | 70 | #define OP_STHU 45 |
67 | 71 | ||
@@ -171,6 +175,19 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
171 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | 175 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); |
172 | break; | 176 | break; |
173 | 177 | ||
178 | case OP_31_XOP_LBZUX: | ||
179 | rt = get_rt(inst); | ||
180 | ra = get_ra(inst); | ||
181 | rb = get_rb(inst); | ||
182 | |||
183 | ea = kvmppc_get_gpr(vcpu, rb); | ||
184 | if (ra) | ||
185 | ea += kvmppc_get_gpr(vcpu, ra); | ||
186 | |||
187 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
188 | kvmppc_set_gpr(vcpu, ra, ea); | ||
189 | break; | ||
190 | |||
174 | case OP_31_XOP_STWX: | 191 | case OP_31_XOP_STWX: |
175 | rs = get_rs(inst); | 192 | rs = get_rs(inst); |
176 | emulated = kvmppc_handle_store(run, vcpu, | 193 | emulated = kvmppc_handle_store(run, vcpu, |
@@ -200,6 +217,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
200 | kvmppc_set_gpr(vcpu, rs, ea); | 217 | kvmppc_set_gpr(vcpu, rs, ea); |
201 | break; | 218 | break; |
202 | 219 | ||
220 | case OP_31_XOP_LHAX: | ||
221 | rt = get_rt(inst); | ||
222 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
223 | break; | ||
224 | |||
203 | case OP_31_XOP_LHZX: | 225 | case OP_31_XOP_LHZX: |
204 | rt = get_rt(inst); | 226 | rt = get_rt(inst); |
205 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | 227 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); |
@@ -450,6 +472,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
450 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); | 472 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); |
451 | break; | 473 | break; |
452 | 474 | ||
475 | case OP_LHA: | ||
476 | rt = get_rt(inst); | ||
477 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
478 | break; | ||
479 | |||
480 | case OP_LHAU: | ||
481 | ra = get_ra(inst); | ||
482 | rt = get_rt(inst); | ||
483 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
484 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); | ||
485 | break; | ||
486 | |||
453 | case OP_STH: | 487 | case OP_STH: |
454 | rs = get_rs(inst); | 488 | rs = get_rs(inst); |
455 | emulated = kvmppc_handle_store(run, vcpu, | 489 | emulated = kvmppc_handle_store(run, vcpu, |
@@ -472,7 +506,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
472 | 506 | ||
473 | if (emulated == EMULATE_FAIL) { | 507 | if (emulated == EMULATE_FAIL) { |
474 | emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); | 508 | emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); |
475 | if (emulated == EMULATE_FAIL) { | 509 | if (emulated == EMULATE_AGAIN) { |
510 | advance = 0; | ||
511 | } else if (emulated == EMULATE_FAIL) { | ||
476 | advance = 0; | 512 | advance = 0; |
477 | printk(KERN_ERR "Couldn't emulate instruction 0x%08x " | 513 | printk(KERN_ERR "Couldn't emulate instruction 0x%08x " |
478 | "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); | 514 | "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); |
diff --git a/arch/powerpc/kvm/fpu.S b/arch/powerpc/kvm/fpu.S new file mode 100644 index 000000000000..2b340a3eee90 --- /dev/null +++ b/arch/powerpc/kvm/fpu.S | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * FPU helper code to use FPU operations from inside the kernel | ||
3 | * | ||
4 | * Copyright (C) 2010 Alexander Graf (agraf@suse.de) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <asm/reg.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/mmu.h> | ||
16 | #include <asm/pgtable.h> | ||
17 | #include <asm/cputable.h> | ||
18 | #include <asm/cache.h> | ||
19 | #include <asm/thread_info.h> | ||
20 | #include <asm/ppc_asm.h> | ||
21 | #include <asm/asm-offsets.h> | ||
22 | |||
23 | /* Instructions operating on single parameters */ | ||
24 | |||
25 | /* | ||
26 | * Single operation with one input operand | ||
27 | * | ||
28 | * R3 = (double*)&fpscr | ||
29 | * R4 = (short*)&result | ||
30 | * R5 = (short*)¶m1 | ||
31 | */ | ||
32 | #define FPS_ONE_IN(name) \ | ||
33 | _GLOBAL(fps_ ## name); \ | ||
34 | lfd 0,0(r3); /* load up fpscr value */ \ | ||
35 | MTFSF_L(0); \ | ||
36 | lfs 0,0(r5); \ | ||
37 | \ | ||
38 | name 0,0; \ | ||
39 | \ | ||
40 | stfs 0,0(r4); \ | ||
41 | mffs 0; \ | ||
42 | stfd 0,0(r3); /* save new fpscr value */ \ | ||
43 | blr | ||
44 | |||
45 | /* | ||
46 | * Single operation with two input operands | ||
47 | * | ||
48 | * R3 = (double*)&fpscr | ||
49 | * R4 = (short*)&result | ||
50 | * R5 = (short*)¶m1 | ||
51 | * R6 = (short*)¶m2 | ||
52 | */ | ||
53 | #define FPS_TWO_IN(name) \ | ||
54 | _GLOBAL(fps_ ## name); \ | ||
55 | lfd 0,0(r3); /* load up fpscr value */ \ | ||
56 | MTFSF_L(0); \ | ||
57 | lfs 0,0(r5); \ | ||
58 | lfs 1,0(r6); \ | ||
59 | \ | ||
60 | name 0,0,1; \ | ||
61 | \ | ||
62 | stfs 0,0(r4); \ | ||
63 | mffs 0; \ | ||
64 | stfd 0,0(r3); /* save new fpscr value */ \ | ||
65 | blr | ||
66 | |||
67 | /* | ||
68 | * Single operation with three input operands | ||
69 | * | ||
70 | * R3 = (double*)&fpscr | ||
71 | * R4 = (short*)&result | ||
72 | * R5 = (short*)¶m1 | ||
73 | * R6 = (short*)¶m2 | ||
74 | * R7 = (short*)¶m3 | ||
75 | */ | ||
76 | #define FPS_THREE_IN(name) \ | ||
77 | _GLOBAL(fps_ ## name); \ | ||
78 | lfd 0,0(r3); /* load up fpscr value */ \ | ||
79 | MTFSF_L(0); \ | ||
80 | lfs 0,0(r5); \ | ||
81 | lfs 1,0(r6); \ | ||
82 | lfs 2,0(r7); \ | ||
83 | \ | ||
84 | name 0,0,1,2; \ | ||
85 | \ | ||
86 | stfs 0,0(r4); \ | ||
87 | mffs 0; \ | ||
88 | stfd 0,0(r3); /* save new fpscr value */ \ | ||
89 | blr | ||
90 | |||
91 | FPS_ONE_IN(fres) | ||
92 | FPS_ONE_IN(frsqrte) | ||
93 | FPS_ONE_IN(fsqrts) | ||
94 | FPS_TWO_IN(fadds) | ||
95 | FPS_TWO_IN(fdivs) | ||
96 | FPS_TWO_IN(fmuls) | ||
97 | FPS_TWO_IN(fsubs) | ||
98 | FPS_THREE_IN(fmadds) | ||
99 | FPS_THREE_IN(fmsubs) | ||
100 | FPS_THREE_IN(fnmadds) | ||
101 | FPS_THREE_IN(fnmsubs) | ||
102 | FPS_THREE_IN(fsel) | ||
103 | |||
104 | |||
105 | /* Instructions operating on double parameters */ | ||
106 | |||
107 | /* | ||
108 | * Beginning of double instruction processing | ||
109 | * | ||
110 | * R3 = (double*)&fpscr | ||
111 | * R4 = (u32*)&cr | ||
112 | * R5 = (double*)&result | ||
113 | * R6 = (double*)¶m1 | ||
114 | * R7 = (double*)¶m2 [load_two] | ||
115 | * R8 = (double*)¶m3 [load_three] | ||
116 | * LR = instruction call function | ||
117 | */ | ||
118 | fpd_load_three: | ||
119 | lfd 2,0(r8) /* load param3 */ | ||
120 | fpd_load_two: | ||
121 | lfd 1,0(r7) /* load param2 */ | ||
122 | fpd_load_one: | ||
123 | lfd 0,0(r6) /* load param1 */ | ||
124 | fpd_load_none: | ||
125 | lfd 3,0(r3) /* load up fpscr value */ | ||
126 | MTFSF_L(3) | ||
127 | lwz r6, 0(r4) /* load cr */ | ||
128 | mtcr r6 | ||
129 | blr | ||
130 | |||
131 | /* | ||
132 | * End of double instruction processing | ||
133 | * | ||
134 | * R3 = (double*)&fpscr | ||
135 | * R4 = (u32*)&cr | ||
136 | * R5 = (double*)&result | ||
137 | * LR = caller of instruction call function | ||
138 | */ | ||
139 | fpd_return: | ||
140 | mfcr r6 | ||
141 | stfd 0,0(r5) /* save result */ | ||
142 | mffs 0 | ||
143 | stfd 0,0(r3) /* save new fpscr value */ | ||
144 | stw r6,0(r4) /* save new cr value */ | ||
145 | blr | ||
146 | |||
147 | /* | ||
148 | * Double operation with no input operand | ||
149 | * | ||
150 | * R3 = (double*)&fpscr | ||
151 | * R4 = (u32*)&cr | ||
152 | * R5 = (double*)&result | ||
153 | */ | ||
154 | #define FPD_NONE_IN(name) \ | ||
155 | _GLOBAL(fpd_ ## name); \ | ||
156 | mflr r12; \ | ||
157 | bl fpd_load_none; \ | ||
158 | mtlr r12; \ | ||
159 | \ | ||
160 | name. 0; /* call instruction */ \ | ||
161 | b fpd_return | ||
162 | |||
163 | /* | ||
164 | * Double operation with one input operand | ||
165 | * | ||
166 | * R3 = (double*)&fpscr | ||
167 | * R4 = (u32*)&cr | ||
168 | * R5 = (double*)&result | ||
169 | * R6 = (double*)¶m1 | ||
170 | */ | ||
171 | #define FPD_ONE_IN(name) \ | ||
172 | _GLOBAL(fpd_ ## name); \ | ||
173 | mflr r12; \ | ||
174 | bl fpd_load_one; \ | ||
175 | mtlr r12; \ | ||
176 | \ | ||
177 | name. 0,0; /* call instruction */ \ | ||
178 | b fpd_return | ||
179 | |||
180 | /* | ||
181 | * Double operation with two input operands | ||
182 | * | ||
183 | * R3 = (double*)&fpscr | ||
184 | * R4 = (u32*)&cr | ||
185 | * R5 = (double*)&result | ||
186 | * R6 = (double*)¶m1 | ||
187 | * R7 = (double*)¶m2 | ||
188 | * R8 = (double*)¶m3 | ||
189 | */ | ||
190 | #define FPD_TWO_IN(name) \ | ||
191 | _GLOBAL(fpd_ ## name); \ | ||
192 | mflr r12; \ | ||
193 | bl fpd_load_two; \ | ||
194 | mtlr r12; \ | ||
195 | \ | ||
196 | name. 0,0,1; /* call instruction */ \ | ||
197 | b fpd_return | ||
198 | |||
199 | /* | ||
200 | * CR Double operation with two input operands | ||
201 | * | ||
202 | * R3 = (double*)&fpscr | ||
203 | * R4 = (u32*)&cr | ||
204 | * R5 = (double*)¶m1 | ||
205 | * R6 = (double*)¶m2 | ||
206 | * R7 = (double*)¶m3 | ||
207 | */ | ||
208 | #define FPD_TWO_IN_CR(name) \ | ||
209 | _GLOBAL(fpd_ ## name); \ | ||
210 | lfd 1,0(r6); /* load param2 */ \ | ||
211 | lfd 0,0(r5); /* load param1 */ \ | ||
212 | lfd 3,0(r3); /* load up fpscr value */ \ | ||
213 | MTFSF_L(3); \ | ||
214 | lwz r6, 0(r4); /* load cr */ \ | ||
215 | mtcr r6; \ | ||
216 | \ | ||
217 | name 0,0,1; /* call instruction */ \ | ||
218 | mfcr r6; \ | ||
219 | mffs 0; \ | ||
220 | stfd 0,0(r3); /* save new fpscr value */ \ | ||
221 | stw r6,0(r4); /* save new cr value */ \ | ||
222 | blr | ||
223 | |||
224 | /* | ||
225 | * Double operation with three input operands | ||
226 | * | ||
227 | * R3 = (double*)&fpscr | ||
228 | * R4 = (u32*)&cr | ||
229 | * R5 = (double*)&result | ||
230 | * R6 = (double*)¶m1 | ||
231 | * R7 = (double*)¶m2 | ||
232 | * R8 = (double*)¶m3 | ||
233 | */ | ||
234 | #define FPD_THREE_IN(name) \ | ||
235 | _GLOBAL(fpd_ ## name); \ | ||
236 | mflr r12; \ | ||
237 | bl fpd_load_three; \ | ||
238 | mtlr r12; \ | ||
239 | \ | ||
240 | name. 0,0,1,2; /* call instruction */ \ | ||
241 | b fpd_return | ||
242 | |||
243 | FPD_ONE_IN(fsqrts) | ||
244 | FPD_ONE_IN(frsqrtes) | ||
245 | FPD_ONE_IN(fres) | ||
246 | FPD_ONE_IN(frsp) | ||
247 | FPD_ONE_IN(fctiw) | ||
248 | FPD_ONE_IN(fctiwz) | ||
249 | FPD_ONE_IN(fsqrt) | ||
250 | FPD_ONE_IN(fre) | ||
251 | FPD_ONE_IN(frsqrte) | ||
252 | FPD_ONE_IN(fneg) | ||
253 | FPD_ONE_IN(fabs) | ||
254 | FPD_TWO_IN(fadds) | ||
255 | FPD_TWO_IN(fsubs) | ||
256 | FPD_TWO_IN(fdivs) | ||
257 | FPD_TWO_IN(fmuls) | ||
258 | FPD_TWO_IN_CR(fcmpu) | ||
259 | FPD_TWO_IN(fcpsgn) | ||
260 | FPD_TWO_IN(fdiv) | ||
261 | FPD_TWO_IN(fadd) | ||
262 | FPD_TWO_IN(fmul) | ||
263 | FPD_TWO_IN_CR(fcmpo) | ||
264 | FPD_TWO_IN(fsub) | ||
265 | FPD_THREE_IN(fmsubs) | ||
266 | FPD_THREE_IN(fmadds) | ||
267 | FPD_THREE_IN(fnmsubs) | ||
268 | FPD_THREE_IN(fnmadds) | ||
269 | FPD_THREE_IN(fsel) | ||
270 | FPD_THREE_IN(fmsub) | ||
271 | FPD_THREE_IN(fmadd) | ||
272 | FPD_THREE_IN(fnmsub) | ||
273 | FPD_THREE_IN(fnmadd) | ||
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 297fcd2ff7d0..ffbe4cac5b15 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -148,6 +148,10 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
148 | 148 | ||
149 | switch (ext) { | 149 | switch (ext) { |
150 | case KVM_CAP_PPC_SEGSTATE: | 150 | case KVM_CAP_PPC_SEGSTATE: |
151 | case KVM_CAP_PPC_PAIRED_SINGLES: | ||
152 | case KVM_CAP_PPC_UNSET_IRQ: | ||
153 | case KVM_CAP_ENABLE_CAP: | ||
154 | case KVM_CAP_PPC_OSI: | ||
151 | r = 1; | 155 | r = 1; |
152 | break; | 156 | break; |
153 | case KVM_CAP_COALESCED_MMIO: | 157 | case KVM_CAP_COALESCED_MMIO: |
@@ -193,12 +197,17 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) | |||
193 | { | 197 | { |
194 | struct kvm_vcpu *vcpu; | 198 | struct kvm_vcpu *vcpu; |
195 | vcpu = kvmppc_core_vcpu_create(kvm, id); | 199 | vcpu = kvmppc_core_vcpu_create(kvm, id); |
196 | kvmppc_create_vcpu_debugfs(vcpu, id); | 200 | if (!IS_ERR(vcpu)) |
201 | kvmppc_create_vcpu_debugfs(vcpu, id); | ||
197 | return vcpu; | 202 | return vcpu; |
198 | } | 203 | } |
199 | 204 | ||
200 | void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) | 205 | void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) |
201 | { | 206 | { |
207 | /* Make sure we're not using the vcpu anymore */ | ||
208 | hrtimer_cancel(&vcpu->arch.dec_timer); | ||
209 | tasklet_kill(&vcpu->arch.tasklet); | ||
210 | |||
202 | kvmppc_remove_vcpu_debugfs(vcpu); | 211 | kvmppc_remove_vcpu_debugfs(vcpu); |
203 | kvmppc_core_vcpu_free(vcpu); | 212 | kvmppc_core_vcpu_free(vcpu); |
204 | } | 213 | } |
@@ -278,7 +287,7 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu, | |||
278 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | 287 | static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, |
279 | struct kvm_run *run) | 288 | struct kvm_run *run) |
280 | { | 289 | { |
281 | ulong gpr; | 290 | u64 gpr; |
282 | 291 | ||
283 | if (run->mmio.len > sizeof(gpr)) { | 292 | if (run->mmio.len > sizeof(gpr)) { |
284 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); | 293 | printk(KERN_ERR "bad MMIO length: %d\n", run->mmio.len); |
@@ -287,6 +296,7 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
287 | 296 | ||
288 | if (vcpu->arch.mmio_is_bigendian) { | 297 | if (vcpu->arch.mmio_is_bigendian) { |
289 | switch (run->mmio.len) { | 298 | switch (run->mmio.len) { |
299 | case 8: gpr = *(u64 *)run->mmio.data; break; | ||
290 | case 4: gpr = *(u32 *)run->mmio.data; break; | 300 | case 4: gpr = *(u32 *)run->mmio.data; break; |
291 | case 2: gpr = *(u16 *)run->mmio.data; break; | 301 | case 2: gpr = *(u16 *)run->mmio.data; break; |
292 | case 1: gpr = *(u8 *)run->mmio.data; break; | 302 | case 1: gpr = *(u8 *)run->mmio.data; break; |
@@ -300,7 +310,43 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
300 | } | 310 | } |
301 | } | 311 | } |
302 | 312 | ||
313 | if (vcpu->arch.mmio_sign_extend) { | ||
314 | switch (run->mmio.len) { | ||
315 | #ifdef CONFIG_PPC64 | ||
316 | case 4: | ||
317 | gpr = (s64)(s32)gpr; | ||
318 | break; | ||
319 | #endif | ||
320 | case 2: | ||
321 | gpr = (s64)(s16)gpr; | ||
322 | break; | ||
323 | case 1: | ||
324 | gpr = (s64)(s8)gpr; | ||
325 | break; | ||
326 | } | ||
327 | } | ||
328 | |||
303 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); | 329 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); |
330 | |||
331 | switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) { | ||
332 | case KVM_REG_GPR: | ||
333 | kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr); | ||
334 | break; | ||
335 | case KVM_REG_FPR: | ||
336 | vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
337 | break; | ||
338 | #ifdef CONFIG_PPC_BOOK3S | ||
339 | case KVM_REG_QPR: | ||
340 | vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
341 | break; | ||
342 | case KVM_REG_FQPR: | ||
343 | vcpu->arch.fpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
344 | vcpu->arch.qpr[vcpu->arch.io_gpr & KVM_REG_MASK] = gpr; | ||
345 | break; | ||
346 | #endif | ||
347 | default: | ||
348 | BUG(); | ||
349 | } | ||
304 | } | 350 | } |
305 | 351 | ||
306 | int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | 352 | int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, |
@@ -319,12 +365,25 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
319 | vcpu->arch.mmio_is_bigendian = is_bigendian; | 365 | vcpu->arch.mmio_is_bigendian = is_bigendian; |
320 | vcpu->mmio_needed = 1; | 366 | vcpu->mmio_needed = 1; |
321 | vcpu->mmio_is_write = 0; | 367 | vcpu->mmio_is_write = 0; |
368 | vcpu->arch.mmio_sign_extend = 0; | ||
322 | 369 | ||
323 | return EMULATE_DO_MMIO; | 370 | return EMULATE_DO_MMIO; |
324 | } | 371 | } |
325 | 372 | ||
373 | /* Same as above, but sign extends */ | ||
374 | int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu, | ||
375 | unsigned int rt, unsigned int bytes, int is_bigendian) | ||
376 | { | ||
377 | int r; | ||
378 | |||
379 | r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian); | ||
380 | vcpu->arch.mmio_sign_extend = 1; | ||
381 | |||
382 | return r; | ||
383 | } | ||
384 | |||
326 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | 385 | int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, |
327 | u32 val, unsigned int bytes, int is_bigendian) | 386 | u64 val, unsigned int bytes, int is_bigendian) |
328 | { | 387 | { |
329 | void *data = run->mmio.data; | 388 | void *data = run->mmio.data; |
330 | 389 | ||
@@ -342,6 +401,7 @@ int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
342 | /* Store the value at the lowest bytes in 'data'. */ | 401 | /* Store the value at the lowest bytes in 'data'. */ |
343 | if (is_bigendian) { | 402 | if (is_bigendian) { |
344 | switch (bytes) { | 403 | switch (bytes) { |
404 | case 8: *(u64 *)data = val; break; | ||
345 | case 4: *(u32 *)data = val; break; | 405 | case 4: *(u32 *)data = val; break; |
346 | case 2: *(u16 *)data = val; break; | 406 | case 2: *(u16 *)data = val; break; |
347 | case 1: *(u8 *)data = val; break; | 407 | case 1: *(u8 *)data = val; break; |
@@ -376,6 +436,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
376 | if (!vcpu->arch.dcr_is_write) | 436 | if (!vcpu->arch.dcr_is_write) |
377 | kvmppc_complete_dcr_load(vcpu, run); | 437 | kvmppc_complete_dcr_load(vcpu, run); |
378 | vcpu->arch.dcr_needed = 0; | 438 | vcpu->arch.dcr_needed = 0; |
439 | } else if (vcpu->arch.osi_needed) { | ||
440 | u64 *gprs = run->osi.gprs; | ||
441 | int i; | ||
442 | |||
443 | for (i = 0; i < 32; i++) | ||
444 | kvmppc_set_gpr(vcpu, i, gprs[i]); | ||
445 | vcpu->arch.osi_needed = 0; | ||
379 | } | 446 | } |
380 | 447 | ||
381 | kvmppc_core_deliver_interrupts(vcpu); | 448 | kvmppc_core_deliver_interrupts(vcpu); |
@@ -396,7 +463,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
396 | 463 | ||
397 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) | 464 | int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) |
398 | { | 465 | { |
399 | kvmppc_core_queue_external(vcpu, irq); | 466 | if (irq->irq == KVM_INTERRUPT_UNSET) |
467 | kvmppc_core_dequeue_external(vcpu, irq); | ||
468 | else | ||
469 | kvmppc_core_queue_external(vcpu, irq); | ||
400 | 470 | ||
401 | if (waitqueue_active(&vcpu->wq)) { | 471 | if (waitqueue_active(&vcpu->wq)) { |
402 | wake_up_interruptible(&vcpu->wq); | 472 | wake_up_interruptible(&vcpu->wq); |
@@ -406,6 +476,27 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) | |||
406 | return 0; | 476 | return 0; |
407 | } | 477 | } |
408 | 478 | ||
479 | static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | ||
480 | struct kvm_enable_cap *cap) | ||
481 | { | ||
482 | int r; | ||
483 | |||
484 | if (cap->flags) | ||
485 | return -EINVAL; | ||
486 | |||
487 | switch (cap->cap) { | ||
488 | case KVM_CAP_PPC_OSI: | ||
489 | r = 0; | ||
490 | vcpu->arch.osi_enabled = true; | ||
491 | break; | ||
492 | default: | ||
493 | r = -EINVAL; | ||
494 | break; | ||
495 | } | ||
496 | |||
497 | return r; | ||
498 | } | ||
499 | |||
409 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | 500 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, |
410 | struct kvm_mp_state *mp_state) | 501 | struct kvm_mp_state *mp_state) |
411 | { | 502 | { |
@@ -434,6 +525,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
434 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); | 525 | r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); |
435 | break; | 526 | break; |
436 | } | 527 | } |
528 | case KVM_ENABLE_CAP: | ||
529 | { | ||
530 | struct kvm_enable_cap cap; | ||
531 | r = -EFAULT; | ||
532 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
533 | goto out; | ||
534 | r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); | ||
535 | break; | ||
536 | } | ||
437 | default: | 537 | default: |
438 | r = -EINVAL; | 538 | r = -EINVAL; |
439 | } | 539 | } |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 7ae71cc56973..bcd6884985ad 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.33-rc2 | 3 | # Linux kernel version: 2.6.34-rc3 |
4 | # Mon Jan 4 09:03:07 2010 | 4 | # Fri Apr 9 09:57:10 2010 |
5 | # | 5 | # |
6 | CONFIG_SCHED_MC=y | 6 | CONFIG_SCHED_MC=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y | |||
17 | CONFIG_GENERIC_TIME_VSYSCALL=y | 17 | CONFIG_GENERIC_TIME_VSYSCALL=y |
18 | CONFIG_GENERIC_CLOCKEVENTS=y | 18 | CONFIG_GENERIC_CLOCKEVENTS=y |
19 | CONFIG_GENERIC_BUG=y | 19 | CONFIG_GENERIC_BUG=y |
20 | CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y | ||
20 | CONFIG_NO_IOMEM=y | 21 | CONFIG_NO_IOMEM=y |
21 | CONFIG_NO_DMA=y | 22 | CONFIG_NO_DMA=y |
22 | CONFIG_GENERIC_LOCKBREAK=y | 23 | CONFIG_GENERIC_LOCKBREAK=y |
@@ -62,15 +63,11 @@ CONFIG_TREE_RCU=y | |||
62 | # CONFIG_RCU_TRACE is not set | 63 | # CONFIG_RCU_TRACE is not set |
63 | CONFIG_RCU_FANOUT=64 | 64 | CONFIG_RCU_FANOUT=64 |
64 | # CONFIG_RCU_FANOUT_EXACT is not set | 65 | # CONFIG_RCU_FANOUT_EXACT is not set |
66 | # CONFIG_RCU_FAST_NO_HZ is not set | ||
65 | # CONFIG_TREE_RCU_TRACE is not set | 67 | # CONFIG_TREE_RCU_TRACE is not set |
66 | CONFIG_IKCONFIG=y | 68 | CONFIG_IKCONFIG=y |
67 | CONFIG_IKCONFIG_PROC=y | 69 | CONFIG_IKCONFIG_PROC=y |
68 | CONFIG_LOG_BUF_SHIFT=17 | 70 | CONFIG_LOG_BUF_SHIFT=17 |
69 | CONFIG_GROUP_SCHED=y | ||
70 | CONFIG_FAIR_GROUP_SCHED=y | ||
71 | # CONFIG_RT_GROUP_SCHED is not set | ||
72 | CONFIG_USER_SCHED=y | ||
73 | # CONFIG_CGROUP_SCHED is not set | ||
74 | CONFIG_CGROUPS=y | 71 | CONFIG_CGROUPS=y |
75 | # CONFIG_CGROUP_DEBUG is not set | 72 | # CONFIG_CGROUP_DEBUG is not set |
76 | CONFIG_CGROUP_NS=y | 73 | CONFIG_CGROUP_NS=y |
@@ -79,6 +76,7 @@ CONFIG_CGROUP_NS=y | |||
79 | # CONFIG_CPUSETS is not set | 76 | # CONFIG_CPUSETS is not set |
80 | # CONFIG_CGROUP_CPUACCT is not set | 77 | # CONFIG_CGROUP_CPUACCT is not set |
81 | # CONFIG_RESOURCE_COUNTERS is not set | 78 | # CONFIG_RESOURCE_COUNTERS is not set |
79 | # CONFIG_CGROUP_SCHED is not set | ||
82 | CONFIG_SYSFS_DEPRECATED=y | 80 | CONFIG_SYSFS_DEPRECATED=y |
83 | CONFIG_SYSFS_DEPRECATED_V2=y | 81 | CONFIG_SYSFS_DEPRECATED_V2=y |
84 | # CONFIG_RELAY is not set | 82 | # CONFIG_RELAY is not set |
@@ -93,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE="" | |||
93 | CONFIG_RD_GZIP=y | 91 | CONFIG_RD_GZIP=y |
94 | CONFIG_RD_BZIP2=y | 92 | CONFIG_RD_BZIP2=y |
95 | CONFIG_RD_LZMA=y | 93 | CONFIG_RD_LZMA=y |
94 | CONFIG_RD_LZO=y | ||
96 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 95 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
97 | CONFIG_SYSCTL=y | 96 | CONFIG_SYSCTL=y |
98 | CONFIG_ANON_INODES=y | 97 | CONFIG_ANON_INODES=y |
@@ -126,6 +125,7 @@ CONFIG_SLAB=y | |||
126 | # CONFIG_SLUB is not set | 125 | # CONFIG_SLUB is not set |
127 | # CONFIG_SLOB is not set | 126 | # CONFIG_SLOB is not set |
128 | # CONFIG_PROFILING is not set | 127 | # CONFIG_PROFILING is not set |
128 | CONFIG_TRACEPOINTS=y | ||
129 | CONFIG_HAVE_OPROFILE=y | 129 | CONFIG_HAVE_OPROFILE=y |
130 | CONFIG_KPROBES=y | 130 | CONFIG_KPROBES=y |
131 | CONFIG_HAVE_SYSCALL_WRAPPERS=y | 131 | CONFIG_HAVE_SYSCALL_WRAPPERS=y |
@@ -134,6 +134,7 @@ CONFIG_HAVE_KPROBES=y | |||
134 | CONFIG_HAVE_KRETPROBES=y | 134 | CONFIG_HAVE_KRETPROBES=y |
135 | CONFIG_HAVE_ARCH_TRACEHOOK=y | 135 | CONFIG_HAVE_ARCH_TRACEHOOK=y |
136 | CONFIG_USE_GENERIC_SMP_HELPERS=y | 136 | CONFIG_USE_GENERIC_SMP_HELPERS=y |
137 | CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y | ||
137 | CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y | 138 | CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y |
138 | 139 | ||
139 | # | 140 | # |
@@ -246,6 +247,7 @@ CONFIG_64BIT=y | |||
246 | CONFIG_SMP=y | 247 | CONFIG_SMP=y |
247 | CONFIG_NR_CPUS=32 | 248 | CONFIG_NR_CPUS=32 |
248 | CONFIG_HOTPLUG_CPU=y | 249 | CONFIG_HOTPLUG_CPU=y |
250 | # CONFIG_SCHED_BOOK is not set | ||
249 | CONFIG_COMPAT=y | 251 | CONFIG_COMPAT=y |
250 | CONFIG_SYSVIPC_COMPAT=y | 252 | CONFIG_SYSVIPC_COMPAT=y |
251 | CONFIG_AUDIT_ARCH=y | 253 | CONFIG_AUDIT_ARCH=y |
@@ -345,13 +347,13 @@ CONFIG_PM_SLEEP=y | |||
345 | CONFIG_HIBERNATION=y | 347 | CONFIG_HIBERNATION=y |
346 | CONFIG_PM_STD_PARTITION="" | 348 | CONFIG_PM_STD_PARTITION="" |
347 | # CONFIG_PM_RUNTIME is not set | 349 | # CONFIG_PM_RUNTIME is not set |
350 | CONFIG_PM_OPS=y | ||
348 | CONFIG_NET=y | 351 | CONFIG_NET=y |
349 | 352 | ||
350 | # | 353 | # |
351 | # Networking options | 354 | # Networking options |
352 | # | 355 | # |
353 | CONFIG_PACKET=y | 356 | CONFIG_PACKET=y |
354 | # CONFIG_PACKET_MMAP is not set | ||
355 | CONFIG_UNIX=y | 357 | CONFIG_UNIX=y |
356 | CONFIG_XFRM=y | 358 | CONFIG_XFRM=y |
357 | # CONFIG_XFRM_USER is not set | 359 | # CONFIG_XFRM_USER is not set |
@@ -529,6 +531,7 @@ CONFIG_NET_SCH_FIFO=y | |||
529 | # | 531 | # |
530 | # CONFIG_NET_PKTGEN is not set | 532 | # CONFIG_NET_PKTGEN is not set |
531 | # CONFIG_NET_TCPPROBE is not set | 533 | # CONFIG_NET_TCPPROBE is not set |
534 | # CONFIG_NET_DROP_MONITOR is not set | ||
532 | CONFIG_CAN=m | 535 | CONFIG_CAN=m |
533 | CONFIG_CAN_RAW=m | 536 | CONFIG_CAN_RAW=m |
534 | CONFIG_CAN_BCM=m | 537 | CONFIG_CAN_BCM=m |
@@ -605,6 +608,7 @@ CONFIG_MISC_DEVICES=y | |||
605 | # | 608 | # |
606 | # SCSI device support | 609 | # SCSI device support |
607 | # | 610 | # |
611 | CONFIG_SCSI_MOD=y | ||
608 | # CONFIG_RAID_ATTRS is not set | 612 | # CONFIG_RAID_ATTRS is not set |
609 | CONFIG_SCSI=y | 613 | CONFIG_SCSI=y |
610 | # CONFIG_SCSI_DMA is not set | 614 | # CONFIG_SCSI_DMA is not set |
@@ -863,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y | |||
863 | # CONFIG_BEFS_FS is not set | 867 | # CONFIG_BEFS_FS is not set |
864 | # CONFIG_BFS_FS is not set | 868 | # CONFIG_BFS_FS is not set |
865 | # CONFIG_EFS_FS is not set | 869 | # CONFIG_EFS_FS is not set |
870 | # CONFIG_LOGFS is not set | ||
866 | # CONFIG_CRAMFS is not set | 871 | # CONFIG_CRAMFS is not set |
867 | # CONFIG_SQUASHFS is not set | 872 | # CONFIG_SQUASHFS is not set |
868 | # CONFIG_VXFS_FS is not set | 873 | # CONFIG_VXFS_FS is not set |
@@ -891,6 +896,7 @@ CONFIG_SUNRPC=y | |||
891 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 896 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
892 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 897 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
893 | # CONFIG_SMB_FS is not set | 898 | # CONFIG_SMB_FS is not set |
899 | # CONFIG_CEPH_FS is not set | ||
894 | # CONFIG_CIFS is not set | 900 | # CONFIG_CIFS is not set |
895 | # CONFIG_NCP_FS is not set | 901 | # CONFIG_NCP_FS is not set |
896 | # CONFIG_CODA_FS is not set | 902 | # CONFIG_CODA_FS is not set |
@@ -952,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y | |||
952 | # CONFIG_LOCK_STAT is not set | 958 | # CONFIG_LOCK_STAT is not set |
953 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | 959 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
954 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | 960 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
961 | CONFIG_STACKTRACE=y | ||
955 | # CONFIG_DEBUG_KOBJECT is not set | 962 | # CONFIG_DEBUG_KOBJECT is not set |
956 | CONFIG_DEBUG_BUGVERBOSE=y | 963 | CONFIG_DEBUG_BUGVERBOSE=y |
957 | # CONFIG_DEBUG_INFO is not set | 964 | # CONFIG_DEBUG_INFO is not set |
@@ -973,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y | |||
973 | # CONFIG_LATENCYTOP is not set | 980 | # CONFIG_LATENCYTOP is not set |
974 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 981 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
975 | # CONFIG_DEBUG_PAGEALLOC is not set | 982 | # CONFIG_DEBUG_PAGEALLOC is not set |
983 | CONFIG_NOP_TRACER=y | ||
976 | CONFIG_HAVE_FUNCTION_TRACER=y | 984 | CONFIG_HAVE_FUNCTION_TRACER=y |
977 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | 985 | CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y |
978 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | 986 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y |
979 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 987 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
980 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 988 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
981 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y | 989 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
990 | CONFIG_RING_BUFFER=y | ||
991 | CONFIG_EVENT_TRACING=y | ||
992 | CONFIG_CONTEXT_SWITCH_TRACER=y | ||
993 | CONFIG_TRACING=y | ||
982 | CONFIG_TRACING_SUPPORT=y | 994 | CONFIG_TRACING_SUPPORT=y |
983 | CONFIG_FTRACE=y | 995 | CONFIG_FTRACE=y |
984 | # CONFIG_FUNCTION_TRACER is not set | 996 | # CONFIG_FUNCTION_TRACER is not set |
@@ -995,10 +1007,15 @@ CONFIG_BRANCH_PROFILE_NONE=y | |||
995 | # CONFIG_KMEMTRACE is not set | 1007 | # CONFIG_KMEMTRACE is not set |
996 | # CONFIG_WORKQUEUE_TRACER is not set | 1008 | # CONFIG_WORKQUEUE_TRACER is not set |
997 | # CONFIG_BLK_DEV_IO_TRACE is not set | 1009 | # CONFIG_BLK_DEV_IO_TRACE is not set |
1010 | CONFIG_KPROBE_EVENT=y | ||
1011 | # CONFIG_RING_BUFFER_BENCHMARK is not set | ||
998 | # CONFIG_DYNAMIC_DEBUG is not set | 1012 | # CONFIG_DYNAMIC_DEBUG is not set |
999 | CONFIG_SAMPLES=y | 1013 | CONFIG_SAMPLES=y |
1014 | # CONFIG_SAMPLE_TRACEPOINTS is not set | ||
1015 | # CONFIG_SAMPLE_TRACE_EVENTS is not set | ||
1000 | # CONFIG_SAMPLE_KOBJECT is not set | 1016 | # CONFIG_SAMPLE_KOBJECT is not set |
1001 | # CONFIG_SAMPLE_KPROBES is not set | 1017 | # CONFIG_SAMPLE_KPROBES is not set |
1018 | # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set | ||
1002 | 1019 | ||
1003 | # | 1020 | # |
1004 | # Security options | 1021 | # Security options |
@@ -1032,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y | |||
1032 | CONFIG_CRYPTO_MANAGER2=y | 1049 | CONFIG_CRYPTO_MANAGER2=y |
1033 | CONFIG_CRYPTO_GF128MUL=m | 1050 | CONFIG_CRYPTO_GF128MUL=m |
1034 | # CONFIG_CRYPTO_NULL is not set | 1051 | # CONFIG_CRYPTO_NULL is not set |
1052 | # CONFIG_CRYPTO_PCRYPT is not set | ||
1035 | CONFIG_CRYPTO_WORKQUEUE=y | 1053 | CONFIG_CRYPTO_WORKQUEUE=y |
1036 | # CONFIG_CRYPTO_CRYPTD is not set | 1054 | # CONFIG_CRYPTO_CRYPTD is not set |
1037 | CONFIG_CRYPTO_AUTHENC=m | 1055 | CONFIG_CRYPTO_AUTHENC=m |
@@ -1119,7 +1137,7 @@ CONFIG_CRYPTO_SHA512_S390=m | |||
1119 | # CONFIG_CRYPTO_DES_S390 is not set | 1137 | # CONFIG_CRYPTO_DES_S390 is not set |
1120 | # CONFIG_CRYPTO_AES_S390 is not set | 1138 | # CONFIG_CRYPTO_AES_S390 is not set |
1121 | CONFIG_S390_PRNG=m | 1139 | CONFIG_S390_PRNG=m |
1122 | # CONFIG_BINARY_PRINTF is not set | 1140 | CONFIG_BINARY_PRINTF=y |
1123 | 1141 | ||
1124 | # | 1142 | # |
1125 | # Library routines | 1143 | # Library routines |
@@ -1136,14 +1154,16 @@ CONFIG_LIBCRC32C=m | |||
1136 | CONFIG_ZLIB_INFLATE=y | 1154 | CONFIG_ZLIB_INFLATE=y |
1137 | CONFIG_ZLIB_DEFLATE=m | 1155 | CONFIG_ZLIB_DEFLATE=m |
1138 | CONFIG_LZO_COMPRESS=m | 1156 | CONFIG_LZO_COMPRESS=m |
1139 | CONFIG_LZO_DECOMPRESS=m | 1157 | CONFIG_LZO_DECOMPRESS=y |
1140 | CONFIG_DECOMPRESS_GZIP=y | 1158 | CONFIG_DECOMPRESS_GZIP=y |
1141 | CONFIG_DECOMPRESS_BZIP2=y | 1159 | CONFIG_DECOMPRESS_BZIP2=y |
1142 | CONFIG_DECOMPRESS_LZMA=y | 1160 | CONFIG_DECOMPRESS_LZMA=y |
1161 | CONFIG_DECOMPRESS_LZO=y | ||
1143 | CONFIG_NLATTR=y | 1162 | CONFIG_NLATTR=y |
1144 | CONFIG_HAVE_KVM=y | 1163 | CONFIG_HAVE_KVM=y |
1145 | CONFIG_VIRTUALIZATION=y | 1164 | CONFIG_VIRTUALIZATION=y |
1146 | CONFIG_KVM=m | 1165 | CONFIG_KVM=m |
1166 | # CONFIG_VHOST_NET is not set | ||
1147 | CONFIG_VIRTIO=y | 1167 | CONFIG_VIRTIO=y |
1148 | CONFIG_VIRTIO_RING=y | 1168 | CONFIG_VIRTIO_RING=y |
1149 | CONFIG_VIRTIO_BALLOON=m | 1169 | CONFIG_VIRTIO_BALLOON=m |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 9b5b9189c15e..89a504c3f12e 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
105 | #ifndef __ASSEMBLY__ | 105 | #ifndef __ASSEMBLY__ |
106 | /* | 106 | /* |
107 | * The vmalloc area will always be on the topmost area of the kernel | 107 | * The vmalloc area will always be on the topmost area of the kernel |
108 | * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc, | 108 | * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc, |
109 | * which should be enough for any sane case. | 109 | * which should be enough for any sane case. |
110 | * By putting vmalloc at the top, we maximise the gap between physical | 110 | * By putting vmalloc at the top, we maximise the gap between physical |
111 | * memory and vmalloc to catch misplaced memory accesses. As a side | 111 | * memory and vmalloc to catch misplaced memory accesses. As a side |
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START; | |||
120 | #define VMALLOC_END 0x7e000000UL | 120 | #define VMALLOC_END 0x7e000000UL |
121 | #define VMEM_MAP_END 0x80000000UL | 121 | #define VMEM_MAP_END 0x80000000UL |
122 | #else /* __s390x__ */ | 122 | #else /* __s390x__ */ |
123 | #define VMALLOC_SIZE (1UL << 30) | 123 | #define VMALLOC_SIZE (128UL << 30) |
124 | #define VMALLOC_END 0x3e040000000UL | 124 | #define VMALLOC_END 0x3e000000000UL |
125 | #define VMEM_MAP_END 0x40000000000UL | 125 | #define VMEM_MAP_END 0x40000000000UL |
126 | #endif /* __s390x__ */ | 126 | #endif /* __s390x__ */ |
127 | 127 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 31d618a443af..2d92c2cf92d7 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -82,7 +82,8 @@ asm( | |||
82 | " lm 6,15,24(15)\n" | 82 | " lm 6,15,24(15)\n" |
83 | #endif | 83 | #endif |
84 | " br 14\n" | 84 | " br 14\n" |
85 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 85 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n" |
86 | " .previous\n"); | ||
86 | 87 | ||
87 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | 88 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; |
88 | 89 | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 4348f9bc5393..6af7045280a8 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -964,7 +964,7 @@ cleanup_critical: | |||
964 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) | 964 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) |
965 | bl BASED(0f) | 965 | bl BASED(0f) |
966 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) | 966 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) |
967 | bl BASED(cleanup_io_return) | 967 | bl BASED(cleanup_io_work_loop) |
968 | 0: | 968 | 0: |
969 | br %r14 | 969 | br %r14 |
970 | 970 | ||
@@ -1039,6 +1039,12 @@ cleanup_sysc_leave_insn: | |||
1039 | 1039 | ||
1040 | cleanup_io_return: | 1040 | cleanup_io_return: |
1041 | mvc __LC_RETURN_PSW(4),0(%r12) | 1041 | mvc __LC_RETURN_PSW(4),0(%r12) |
1042 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) | ||
1043 | la %r12,__LC_RETURN_PSW | ||
1044 | br %r14 | ||
1045 | |||
1046 | cleanup_io_work_loop: | ||
1047 | mvc __LC_RETURN_PSW(4),0(%r12) | ||
1042 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) | 1048 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) |
1043 | la %r12,__LC_RETURN_PSW | 1049 | la %r12,__LC_RETURN_PSW |
1044 | br %r14 | 1050 | br %r14 |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 29fd0f1e6ec4..52106d53271c 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -946,7 +946,7 @@ cleanup_critical: | |||
946 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop) | 946 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop) |
947 | jl 0f | 947 | jl 0f |
948 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) | 948 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) |
949 | jl cleanup_io_return | 949 | jl cleanup_io_work_loop |
950 | 0: | 950 | 0: |
951 | br %r14 | 951 | br %r14 |
952 | 952 | ||
@@ -1021,6 +1021,12 @@ cleanup_sysc_leave_insn: | |||
1021 | 1021 | ||
1022 | cleanup_io_return: | 1022 | cleanup_io_return: |
1023 | mvc __LC_RETURN_PSW(8),0(%r12) | 1023 | mvc __LC_RETURN_PSW(8),0(%r12) |
1024 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) | ||
1025 | la %r12,__LC_RETURN_PSW | ||
1026 | br %r14 | ||
1027 | |||
1028 | cleanup_io_work_loop: | ||
1029 | mvc __LC_RETURN_PSW(8),0(%r12) | ||
1024 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) | 1030 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) |
1025 | la %r12,__LC_RETURN_PSW | 1031 | la %r12,__LC_RETURN_PSW |
1026 | br %r14 | 1032 | br %r14 |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 14ef6f05e432..247b4c2d1e51 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *info) | |||
165 | default: | 165 | default: |
166 | clear_cores(); | 166 | clear_cores(); |
167 | machine_has_topology = 0; | 167 | machine_has_topology = 0; |
168 | return; | 168 | goto out; |
169 | } | 169 | } |
170 | tle = next_tle(tle); | 170 | tle = next_tle(tle); |
171 | } | 171 | } |
172 | out: | ||
172 | spin_unlock_irq(&topology_lock); | 173 | spin_unlock_irq(&topology_lock); |
173 | } | 174 | } |
174 | 175 | ||
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 49292869a5cd..ee7c713686ce 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -341,11 +341,13 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
341 | 341 | ||
342 | rc = kvm_vcpu_init(vcpu, kvm, id); | 342 | rc = kvm_vcpu_init(vcpu, kvm, id); |
343 | if (rc) | 343 | if (rc) |
344 | goto out_free_cpu; | 344 | goto out_free_sie_block; |
345 | VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, | 345 | VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, |
346 | vcpu->arch.sie_block); | 346 | vcpu->arch.sie_block); |
347 | 347 | ||
348 | return vcpu; | 348 | return vcpu; |
349 | out_free_sie_block: | ||
350 | free_page((unsigned long)(vcpu->arch.sie_block)); | ||
349 | out_free_cpu: | 351 | out_free_cpu: |
350 | kfree(vcpu); | 352 | kfree(vcpu); |
351 | out_nomem: | 353 | out_nomem: |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 8ea3144b45b8..90165e7ca04e 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -71,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void) | |||
71 | pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t)); | 71 | pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t)); |
72 | if (!pte) | 72 | if (!pte) |
73 | return NULL; | 73 | return NULL; |
74 | if (MACHINE_HAS_HPAGE) | 74 | clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, |
75 | clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO, | 75 | PTRS_PER_PTE * sizeof(pte_t)); |
76 | PTRS_PER_PTE * sizeof(pte_t)); | ||
77 | else | ||
78 | clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, | ||
79 | PTRS_PER_PTE * sizeof(pte_t)); | ||
80 | return pte; | 76 | return pte; |
81 | } | 77 | } |
82 | 78 | ||
@@ -117,8 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) | |||
117 | if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && | 113 | if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && |
118 | (address + HPAGE_SIZE <= start + size) && | 114 | (address + HPAGE_SIZE <= start + size) && |
119 | (address >= HPAGE_SIZE)) { | 115 | (address >= HPAGE_SIZE)) { |
120 | pte_val(pte) |= _SEGMENT_ENTRY_LARGE | | 116 | pte_val(pte) |= _SEGMENT_ENTRY_LARGE; |
121 | _SEGMENT_ENTRY_CO; | ||
122 | pmd_val(*pm_dir) = pte_val(pte); | 117 | pmd_val(*pm_dir) = pte_val(pte); |
123 | address += HPAGE_SIZE - PAGE_SIZE; | 118 | address += HPAGE_SIZE - PAGE_SIZE; |
124 | continue; | 119 | continue; |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6db513674050..9908d477ccd9 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -37,6 +37,9 @@ config SPARC64 | |||
37 | def_bool 64BIT | 37 | def_bool 64BIT |
38 | select ARCH_SUPPORTS_MSI | 38 | select ARCH_SUPPORTS_MSI |
39 | select HAVE_FUNCTION_TRACER | 39 | select HAVE_FUNCTION_TRACER |
40 | select HAVE_FUNCTION_GRAPH_TRACER | ||
41 | select HAVE_FUNCTION_GRAPH_FP_TEST | ||
42 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
40 | select HAVE_KRETPROBES | 43 | select HAVE_KRETPROBES |
41 | select HAVE_KPROBES | 44 | select HAVE_KPROBES |
42 | select HAVE_LMB | 45 | select HAVE_LMB |
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug index 9d3c889718ac..1b4a831565f9 100644 --- a/arch/sparc/Kconfig.debug +++ b/arch/sparc/Kconfig.debug | |||
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH | |||
19 | bool "D-cache flush debugging" | 19 | bool "D-cache flush debugging" |
20 | depends on SPARC64 && DEBUG_KERNEL | 20 | depends on SPARC64 && DEBUG_KERNEL |
21 | 21 | ||
22 | config STACK_DEBUG | ||
23 | bool "Stack Overflow Detection Support" | ||
24 | |||
25 | config MCOUNT | 22 | config MCOUNT |
26 | bool | 23 | bool |
27 | depends on SPARC64 | 24 | depends on SPARC64 |
28 | depends on STACK_DEBUG || FUNCTION_TRACER | 25 | depends on FUNCTION_TRACER |
29 | default y | 26 | default y |
30 | 27 | ||
31 | config FRAME_POINTER | 28 | config FRAME_POINTER |
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index 926397d345ff..050ef35b9dcf 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h | |||
@@ -17,7 +17,7 @@ typedef struct { | |||
17 | unsigned int __nmi_count; | 17 | unsigned int __nmi_count; |
18 | unsigned long clock_tick; /* %tick's per second */ | 18 | unsigned long clock_tick; /* %tick's per second */ |
19 | unsigned long __pad; | 19 | unsigned long __pad; |
20 | unsigned int __pad1; | 20 | unsigned int irq0_irqs; |
21 | unsigned int __pad2; | 21 | unsigned int __pad2; |
22 | 22 | ||
23 | /* Dcache line 2, rarely used */ | 23 | /* Dcache line 2, rarely used */ |
diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index 8b49bf920df3..bfa1ea45b4cd 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h | |||
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void) | |||
76 | */ | 76 | */ |
77 | static inline unsigned long __raw_local_irq_save(void) | 77 | static inline unsigned long __raw_local_irq_save(void) |
78 | { | 78 | { |
79 | unsigned long flags = __raw_local_save_flags(); | 79 | unsigned long flags, tmp; |
80 | 80 | ||
81 | raw_local_irq_disable(); | 81 | /* Disable interrupts to PIL_NORMAL_MAX unless we already |
82 | * are using PIL_NMI, in which case PIL_NMI is retained. | ||
83 | * | ||
84 | * The only values we ever program into the %pil are 0, | ||
85 | * PIL_NORMAL_MAX and PIL_NMI. | ||
86 | * | ||
87 | * Since PIL_NMI is the largest %pil value and all bits are | ||
88 | * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX | ||
89 | * actually is. | ||
90 | */ | ||
91 | __asm__ __volatile__( | ||
92 | "rdpr %%pil, %0\n\t" | ||
93 | "or %0, %2, %1\n\t" | ||
94 | "wrpr %1, 0x0, %%pil" | ||
95 | : "=r" (flags), "=r" (tmp) | ||
96 | : "i" (PIL_NORMAL_MAX) | ||
97 | : "memory" | ||
98 | ); | ||
82 | 99 | ||
83 | return flags; | 100 | return flags; |
84 | } | 101 | } |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 9e2d9447f2ad..4827a3aeac7f 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
@@ -111,7 +111,7 @@ struct thread_info { | |||
111 | #define THREAD_SHIFT PAGE_SHIFT | 111 | #define THREAD_SHIFT PAGE_SHIFT |
112 | #endif /* PAGE_SHIFT == 13 */ | 112 | #endif /* PAGE_SHIFT == 13 */ |
113 | 113 | ||
114 | #define PREEMPT_ACTIVE 0x4000000 | 114 | #define PREEMPT_ACTIVE 0x10000000 |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * macros/functions for gaining access to the thread information structure | 117 | * macros/functions for gaining access to the thread information structure |
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index c6316142db4e..0c2dc1f24a9a 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
@@ -13,6 +13,14 @@ extra-y += init_task.o | |||
13 | CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) | 13 | CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS) |
14 | extra-y += vmlinux.lds | 14 | extra-y += vmlinux.lds |
15 | 15 | ||
16 | ifdef CONFIG_FUNCTION_TRACER | ||
17 | # Do not profile debug and lowlevel utilities | ||
18 | CFLAGS_REMOVE_ftrace.o := -pg | ||
19 | CFLAGS_REMOVE_time_$(BITS).o := -pg | ||
20 | CFLAGS_REMOVE_perf_event.o := -pg | ||
21 | CFLAGS_REMOVE_pcr.o := -pg | ||
22 | endif | ||
23 | |||
16 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o | 24 | obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o |
17 | obj-$(CONFIG_SPARC32) += etrap_32.o | 25 | obj-$(CONFIG_SPARC32) += etrap_32.o |
18 | obj-$(CONFIG_SPARC32) += rtrap_32.o | 26 | obj-$(CONFIG_SPARC32) += rtrap_32.o |
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o | |||
85 | 93 | ||
86 | 94 | ||
87 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 95 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
88 | CFLAGS_REMOVE_ftrace.o := -pg | 96 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
89 | 97 | ||
90 | obj-$(CONFIG_EARLYFB) += btext.o | 98 | obj-$(CONFIG_EARLYFB) += btext.o |
91 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 99 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index 9103a56b39e8..03ab022e51c5 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c | |||
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000; | |||
13 | 13 | ||
14 | static u32 ftrace_call_replace(unsigned long ip, unsigned long addr) | 14 | static u32 ftrace_call_replace(unsigned long ip, unsigned long addr) |
15 | { | 15 | { |
16 | static u32 call; | 16 | u32 call; |
17 | s32 off; | 17 | s32 off; |
18 | 18 | ||
19 | off = ((s32)addr - (s32)ip); | 19 | off = ((s32)addr - (s32)ip); |
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data) | |||
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | #endif | 93 | #endif |
94 | |||
95 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
96 | |||
97 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
98 | extern void ftrace_graph_call(void); | ||
99 | |||
100 | int ftrace_enable_ftrace_graph_caller(void) | ||
101 | { | ||
102 | unsigned long ip = (unsigned long)(&ftrace_graph_call); | ||
103 | u32 old, new; | ||
104 | |||
105 | old = *(u32 *) &ftrace_graph_call; | ||
106 | new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller); | ||
107 | return ftrace_modify_code(ip, old, new); | ||
108 | } | ||
109 | |||
110 | int ftrace_disable_ftrace_graph_caller(void) | ||
111 | { | ||
112 | unsigned long ip = (unsigned long)(&ftrace_graph_call); | ||
113 | u32 old, new; | ||
114 | |||
115 | old = *(u32 *) &ftrace_graph_call; | ||
116 | new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub); | ||
117 | |||
118 | return ftrace_modify_code(ip, old, new); | ||
119 | } | ||
120 | |||
121 | #endif /* !CONFIG_DYNAMIC_FTRACE */ | ||
122 | |||
123 | /* | ||
124 | * Hook the return address and push it in the stack of return addrs | ||
125 | * in current thread info. | ||
126 | */ | ||
127 | unsigned long prepare_ftrace_return(unsigned long parent, | ||
128 | unsigned long self_addr, | ||
129 | unsigned long frame_pointer) | ||
130 | { | ||
131 | unsigned long return_hooker = (unsigned long) &return_to_handler; | ||
132 | struct ftrace_graph_ent trace; | ||
133 | |||
134 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | ||
135 | return parent + 8UL; | ||
136 | |||
137 | if (ftrace_push_return_trace(parent, self_addr, &trace.depth, | ||
138 | frame_pointer) == -EBUSY) | ||
139 | return parent + 8UL; | ||
140 | |||
141 | trace.func = self_addr; | ||
142 | |||
143 | /* Only trace if the calling function expects to */ | ||
144 | if (!ftrace_graph_entry(&trace)) { | ||
145 | current->curr_ret_stack--; | ||
146 | return parent + 8UL; | ||
147 | } | ||
148 | |||
149 | return return_hooker; | ||
150 | } | ||
151 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e1cbdb94d97b..830d70a3e20b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -20,7 +20,9 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/ftrace.h> | ||
23 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/kmemleak.h> | ||
24 | 26 | ||
25 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
26 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
@@ -45,6 +47,7 @@ | |||
45 | 47 | ||
46 | #include "entry.h" | 48 | #include "entry.h" |
47 | #include "cpumap.h" | 49 | #include "cpumap.h" |
50 | #include "kstack.h" | ||
48 | 51 | ||
49 | #define NUM_IVECS (IMAP_INR + 1) | 52 | #define NUM_IVECS (IMAP_INR + 1) |
50 | 53 | ||
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | |||
647 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); | 650 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); |
648 | if (unlikely(!bucket)) | 651 | if (unlikely(!bucket)) |
649 | return 0; | 652 | return 0; |
653 | |||
654 | /* The only reference we store to the IRQ bucket is | ||
655 | * by physical address which kmemleak can't see, tell | ||
656 | * it that this object explicitly is not a leak and | ||
657 | * should be scanned. | ||
658 | */ | ||
659 | kmemleak_not_leak(bucket); | ||
660 | |||
650 | __flush_dcache_range((unsigned long) bucket, | 661 | __flush_dcache_range((unsigned long) bucket, |
651 | ((unsigned long) bucket + | 662 | ((unsigned long) bucket + |
652 | sizeof(struct ino_bucket))); | 663 | sizeof(struct ino_bucket))); |
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq) | |||
703 | void *hardirq_stack[NR_CPUS]; | 714 | void *hardirq_stack[NR_CPUS]; |
704 | void *softirq_stack[NR_CPUS]; | 715 | void *softirq_stack[NR_CPUS]; |
705 | 716 | ||
706 | static __attribute__((always_inline)) void *set_hardirq_stack(void) | 717 | void __irq_entry handler_irq(int irq, struct pt_regs *regs) |
707 | { | ||
708 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
709 | |||
710 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
711 | if (orig_sp < sp || | ||
712 | orig_sp > (sp + THREAD_SIZE)) { | ||
713 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
714 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
715 | } | ||
716 | |||
717 | return orig_sp; | ||
718 | } | ||
719 | static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
720 | { | ||
721 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
722 | } | ||
723 | |||
724 | void handler_irq(int irq, struct pt_regs *regs) | ||
725 | { | 718 | { |
726 | unsigned long pstate, bucket_pa; | 719 | unsigned long pstate, bucket_pa; |
727 | struct pt_regs *old_regs; | 720 | struct pt_regs *old_regs; |
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index f5a0fd490b59..0a2bd0f99fc1 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kgdb.h> | 6 | #include <linux/kgdb.h> |
7 | #include <linux/kdebug.h> | 7 | #include <linux/kdebug.h> |
8 | #include <linux/ftrace.h> | ||
8 | 9 | ||
9 | #include <asm/kdebug.h> | 10 | #include <asm/kdebug.h> |
10 | #include <asm/ptrace.h> | 11 | #include <asm/ptrace.h> |
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
108 | } | 109 | } |
109 | 110 | ||
110 | #ifdef CONFIG_SMP | 111 | #ifdef CONFIG_SMP |
111 | void smp_kgdb_capture_client(int irq, struct pt_regs *regs) | 112 | void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs) |
112 | { | 113 | { |
113 | unsigned long flags; | 114 | unsigned long flags; |
114 | 115 | ||
diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h index 5247283d1c03..53dfb92e09fb 100644 --- a/arch/sparc/kernel/kstack.h +++ b/arch/sparc/kernel/kstack.h | |||
@@ -61,4 +61,23 @@ check_magic: | |||
61 | 61 | ||
62 | } | 62 | } |
63 | 63 | ||
64 | static inline __attribute__((always_inline)) void *set_hardirq_stack(void) | ||
65 | { | ||
66 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
67 | |||
68 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
69 | if (orig_sp < sp || | ||
70 | orig_sp > (sp + THREAD_SIZE)) { | ||
71 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
72 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
73 | } | ||
74 | |||
75 | return orig_sp; | ||
76 | } | ||
77 | |||
78 | static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
79 | { | ||
80 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
81 | } | ||
82 | |||
64 | #endif /* _KSTACK_H */ | 83 | #endif /* _KSTACK_H */ |
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index b287b62c7ea3..a4bd7ba74c89 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
24 | #include <asm/pcr.h> | 24 | #include <asm/pcr.h> |
25 | 25 | ||
26 | #include "kstack.h" | ||
27 | |||
26 | /* We don't have a real NMI on sparc64, but we can fake one | 28 | /* We don't have a real NMI on sparc64, but we can fake one |
27 | * up using profiling counter overflow interrupts and interrupt | 29 | * up using profiling counter overflow interrupts and interrupt |
28 | * levels. | 30 | * levels. |
@@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) | |||
92 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | 94 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) |
93 | { | 95 | { |
94 | unsigned int sum, touched = 0; | 96 | unsigned int sum, touched = 0; |
95 | int cpu = smp_processor_id(); | 97 | void *orig_sp; |
96 | 98 | ||
97 | clear_softint(1 << irq); | 99 | clear_softint(1 << irq); |
98 | 100 | ||
@@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | |||
100 | 102 | ||
101 | nmi_enter(); | 103 | nmi_enter(); |
102 | 104 | ||
105 | orig_sp = set_hardirq_stack(); | ||
106 | |||
103 | if (notify_die(DIE_NMI, "nmi", regs, 0, | 107 | if (notify_die(DIE_NMI, "nmi", regs, 0, |
104 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) | 108 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) |
105 | touched = 1; | 109 | touched = 1; |
106 | else | 110 | else |
107 | pcr_ops->write(PCR_PIC_PRIV); | 111 | pcr_ops->write(PCR_PIC_PRIV); |
108 | 112 | ||
109 | sum = kstat_irqs_cpu(0, cpu); | 113 | sum = local_cpu_data().irq0_irqs; |
110 | if (__get_cpu_var(nmi_touch)) { | 114 | if (__get_cpu_var(nmi_touch)) { |
111 | __get_cpu_var(nmi_touch) = 0; | 115 | __get_cpu_var(nmi_touch) = 0; |
112 | touched = 1; | 116 | touched = 1; |
@@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | |||
125 | pcr_ops->write(pcr_enable); | 129 | pcr_ops->write(pcr_enable); |
126 | } | 130 | } |
127 | 131 | ||
132 | restore_hardirq_stack(orig_sp); | ||
133 | |||
128 | nmi_exit(); | 134 | nmi_exit(); |
129 | } | 135 | } |
130 | 136 | ||
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index b775658a927d..8a000583b5cf 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c | |||
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) | |||
371 | struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); | 371 | struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); |
372 | 372 | ||
373 | if (!rp) { | 373 | if (!rp) { |
374 | prom_printf("Cannot allocate IOMMU resource.\n"); | 374 | pr_info("%s: Cannot allocate IOMMU resource.\n", |
375 | prom_halt(); | 375 | pbm->name); |
376 | return; | ||
376 | } | 377 | } |
377 | rp->name = "IOMMU"; | 378 | rp->name = "IOMMU"; |
378 | rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; | 379 | rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; |
379 | rp->end = rp->start + (unsigned long) vdma[1] - 1UL; | 380 | rp->end = rp->start + (unsigned long) vdma[1] - 1UL; |
380 | rp->flags = IORESOURCE_BUSY; | 381 | rp->flags = IORESOURCE_BUSY; |
381 | request_resource(&pbm->mem_space, rp); | 382 | if (request_resource(&pbm->mem_space, rp)) { |
383 | pr_info("%s: Unable to request IOMMU resource.\n", | ||
384 | pbm->name); | ||
385 | kfree(rp); | ||
386 | } | ||
382 | } | 387 | } |
383 | } | 388 | } |
384 | 389 | ||
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 2d94e7a03af5..c4a6a50b4849 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
9 | 9 | ||
10 | #include <linux/perf_event.h> | 10 | #include <linux/perf_event.h> |
11 | #include <linux/ftrace.h> | ||
11 | 12 | ||
12 | #include <asm/pil.h> | 13 | #include <asm/pil.h> |
13 | #include <asm/pcr.h> | 14 | #include <asm/pcr.h> |
@@ -34,7 +35,7 @@ unsigned int picl_shift; | |||
34 | * Therefore in such situations we defer the work by signalling | 35 | * Therefore in such situations we defer the work by signalling |
35 | * a lower level cpu IRQ. | 36 | * a lower level cpu IRQ. |
36 | */ | 37 | */ |
37 | void deferred_pcr_work_irq(int irq, struct pt_regs *regs) | 38 | void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs) |
38 | { | 39 | { |
39 | struct pt_regs *old_regs; | 40 | struct pt_regs *old_regs; |
40 | 41 | ||
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 83f1873c6c13..090b9e9ad5e3 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S | |||
@@ -130,7 +130,17 @@ rtrap_xcall: | |||
130 | nop | 130 | nop |
131 | call trace_hardirqs_on | 131 | call trace_hardirqs_on |
132 | nop | 132 | nop |
133 | wrpr %l4, %pil | 133 | /* Do not actually set the %pil here. We will do that |
134 | * below after we clear PSTATE_IE in the %pstate register. | ||
135 | * If we re-enable interrupts here, we can recurse down | ||
136 | * the hardirq stack potentially endlessly, causing a | ||
137 | * stack overflow. | ||
138 | * | ||
139 | * It is tempting to put this test and trace_hardirqs_on | ||
140 | * call at the 'rt_continue' label, but that will not work | ||
141 | * as that path hits unconditionally and we do not want to | ||
142 | * execute this in NMI return paths, for example. | ||
143 | */ | ||
134 | #endif | 144 | #endif |
135 | rtrap_no_irq_enable: | 145 | rtrap_no_irq_enable: |
136 | andcc %l1, TSTATE_PRIV, %l3 | 146 | andcc %l1, TSTATE_PRIV, %l3 |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 4c5334528109..b6a2b8f47040 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/profile.h> | 22 | #include <linux/profile.h> |
23 | #include <linux/bootmem.h> | 23 | #include <linux/bootmem.h> |
24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
25 | #include <linux/ftrace.h> | ||
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | 28 | ||
@@ -823,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu) | |||
823 | &cpumask_of_cpu(cpu)); | 824 | &cpumask_of_cpu(cpu)); |
824 | } | 825 | } |
825 | 826 | ||
826 | void smp_call_function_client(int irq, struct pt_regs *regs) | 827 | void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs) |
827 | { | 828 | { |
828 | clear_softint(1 << irq); | 829 | clear_softint(1 << irq); |
829 | generic_smp_call_function_interrupt(); | 830 | generic_smp_call_function_interrupt(); |
830 | } | 831 | } |
831 | 832 | ||
832 | void smp_call_function_single_client(int irq, struct pt_regs *regs) | 833 | void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs) |
833 | { | 834 | { |
834 | clear_softint(1 << irq); | 835 | clear_softint(1 << irq); |
835 | generic_smp_call_function_single_interrupt(); | 836 | generic_smp_call_function_single_interrupt(); |
@@ -965,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page) | |||
965 | put_cpu(); | 966 | put_cpu(); |
966 | } | 967 | } |
967 | 968 | ||
968 | void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) | 969 | void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) |
969 | { | 970 | { |
970 | struct mm_struct *mm; | 971 | struct mm_struct *mm; |
971 | unsigned long flags; | 972 | unsigned long flags; |
@@ -1149,7 +1150,7 @@ void smp_release(void) | |||
1149 | */ | 1150 | */ |
1150 | extern void prom_world(int); | 1151 | extern void prom_world(int); |
1151 | 1152 | ||
1152 | void smp_penguin_jailcell(int irq, struct pt_regs *regs) | 1153 | void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs) |
1153 | { | 1154 | { |
1154 | clear_softint(1 << irq); | 1155 | clear_softint(1 << irq); |
1155 | 1156 | ||
@@ -1365,7 +1366,7 @@ void smp_send_reschedule(int cpu) | |||
1365 | &cpumask_of_cpu(cpu)); | 1366 | &cpumask_of_cpu(cpu)); |
1366 | } | 1367 | } |
1367 | 1368 | ||
1368 | void smp_receive_signal_client(int irq, struct pt_regs *regs) | 1369 | void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) |
1369 | { | 1370 | { |
1370 | clear_softint(1 << irq); | 1371 | clear_softint(1 << irq); |
1371 | } | 1372 | } |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 67e165102885..c7bbe6cf7b85 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clocksource.h> | 35 | #include <linux/clocksource.h> |
36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/ftrace.h> | ||
38 | 39 | ||
39 | #include <asm/oplib.h> | 40 | #include <asm/oplib.h> |
40 | #include <asm/timer.h> | 41 | #include <asm/timer.h> |
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = { | |||
717 | }; | 718 | }; |
718 | static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); | 719 | static DEFINE_PER_CPU(struct clock_event_device, sparc64_events); |
719 | 720 | ||
720 | void timer_interrupt(int irq, struct pt_regs *regs) | 721 | void __irq_entry timer_interrupt(int irq, struct pt_regs *regs) |
721 | { | 722 | { |
722 | struct pt_regs *old_regs = set_irq_regs(regs); | 723 | struct pt_regs *old_regs = set_irq_regs(regs); |
723 | unsigned long tick_mask = tick_ops->softint_mask; | 724 | unsigned long tick_mask = tick_ops->softint_mask; |
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs) | |||
728 | 729 | ||
729 | irq_enter(); | 730 | irq_enter(); |
730 | 731 | ||
732 | local_cpu_data().irq0_irqs++; | ||
731 | kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); | 733 | kstat_incr_irqs_this_cpu(0, irq_to_desc(0)); |
732 | 734 | ||
733 | if (unlikely(!evt->event_handler)) { | 735 | if (unlikely(!evt->event_handler)) { |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 837dfc2390d6..9da57f032983 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -2203,27 +2203,6 @@ void dump_stack(void) | |||
2203 | 2203 | ||
2204 | EXPORT_SYMBOL(dump_stack); | 2204 | EXPORT_SYMBOL(dump_stack); |
2205 | 2205 | ||
2206 | static inline int is_kernel_stack(struct task_struct *task, | ||
2207 | struct reg_window *rw) | ||
2208 | { | ||
2209 | unsigned long rw_addr = (unsigned long) rw; | ||
2210 | unsigned long thread_base, thread_end; | ||
2211 | |||
2212 | if (rw_addr < PAGE_OFFSET) { | ||
2213 | if (task != &init_task) | ||
2214 | return 0; | ||
2215 | } | ||
2216 | |||
2217 | thread_base = (unsigned long) task_stack_page(task); | ||
2218 | thread_end = thread_base + sizeof(union thread_union); | ||
2219 | if (rw_addr >= thread_base && | ||
2220 | rw_addr < thread_end && | ||
2221 | !(rw_addr & 0x7UL)) | ||
2222 | return 1; | ||
2223 | |||
2224 | return 0; | ||
2225 | } | ||
2226 | |||
2227 | static inline struct reg_window *kernel_stack_up(struct reg_window *rw) | 2206 | static inline struct reg_window *kernel_stack_up(struct reg_window *rw) |
2228 | { | 2207 | { |
2229 | unsigned long fp = rw->ins[6]; | 2208 | unsigned long fp = rw->ins[6]; |
@@ -2252,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2252 | show_regs(regs); | 2231 | show_regs(regs); |
2253 | add_taint(TAINT_DIE); | 2232 | add_taint(TAINT_DIE); |
2254 | if (regs->tstate & TSTATE_PRIV) { | 2233 | if (regs->tstate & TSTATE_PRIV) { |
2234 | struct thread_info *tp = current_thread_info(); | ||
2255 | struct reg_window *rw = (struct reg_window *) | 2235 | struct reg_window *rw = (struct reg_window *) |
2256 | (regs->u_regs[UREG_FP] + STACK_BIAS); | 2236 | (regs->u_regs[UREG_FP] + STACK_BIAS); |
2257 | 2237 | ||
@@ -2259,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs) | |||
2259 | * find some badly aligned kernel stack. | 2239 | * find some badly aligned kernel stack. |
2260 | */ | 2240 | */ |
2261 | while (rw && | 2241 | while (rw && |
2262 | count++ < 30&& | 2242 | count++ < 30 && |
2263 | is_kernel_stack(current, rw)) { | 2243 | kstack_valid(tp, (unsigned long) rw)) { |
2264 | printk("Caller[%016lx]: %pS\n", rw->ins[7], | 2244 | printk("Caller[%016lx]: %pS\n", rw->ins[7], |
2265 | (void *) rw->ins[7]); | 2245 | (void *) rw->ins[7]); |
2266 | 2246 | ||
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index ebce43018c49..c752c4c479bd 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn) | |||
50 | } | 50 | } |
51 | 51 | ||
52 | /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ | 52 | /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ |
53 | static inline int decode_access_size(unsigned int insn) | 53 | static inline int decode_access_size(struct pt_regs *regs, unsigned int insn) |
54 | { | 54 | { |
55 | unsigned int tmp; | 55 | unsigned int tmp; |
56 | 56 | ||
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn) | |||
66 | return 2; | 66 | return 2; |
67 | else { | 67 | else { |
68 | printk("Impossible unaligned trap. insn=%08x\n", insn); | 68 | printk("Impossible unaligned trap. insn=%08x\n", insn); |
69 | die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); | 69 | die_if_kernel("Byte sized unaligned access?!?!", regs); |
70 | 70 | ||
71 | /* GCC should never warn that control reaches the end | 71 | /* GCC should never warn that control reaches the end |
72 | * of this function without returning a value because | 72 | * of this function without returning a value because |
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs) | |||
286 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) | 286 | asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) |
287 | { | 287 | { |
288 | enum direction dir = decode_direction(insn); | 288 | enum direction dir = decode_direction(insn); |
289 | int size = decode_access_size(insn); | 289 | int size = decode_access_size(regs, insn); |
290 | int orig_asi, asi; | 290 | int orig_asi, asi; |
291 | 291 | ||
292 | current_thread_info()->kern_una_regs = regs; | 292 | current_thread_info()->kern_una_regs = regs; |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 4e5992593967..0c1e6783657f 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -46,11 +46,16 @@ SECTIONS | |||
46 | SCHED_TEXT | 46 | SCHED_TEXT |
47 | LOCK_TEXT | 47 | LOCK_TEXT |
48 | KPROBES_TEXT | 48 | KPROBES_TEXT |
49 | IRQENTRY_TEXT | ||
49 | *(.gnu.warning) | 50 | *(.gnu.warning) |
50 | } = 0 | 51 | } = 0 |
51 | _etext = .; | 52 | _etext = .; |
52 | 53 | ||
53 | RO_DATA(PAGE_SIZE) | 54 | RO_DATA(PAGE_SIZE) |
55 | |||
56 | /* Start of data section */ | ||
57 | _sdata = .; | ||
58 | |||
54 | .data1 : { | 59 | .data1 : { |
55 | *(.data1) | 60 | *(.data1) |
56 | } | 61 | } |
diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 24b8b12deed2..3ad6cbdc2163 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S | |||
@@ -7,26 +7,11 @@ | |||
7 | 7 | ||
8 | #include <linux/linkage.h> | 8 | #include <linux/linkage.h> |
9 | 9 | ||
10 | #include <asm/ptrace.h> | ||
11 | #include <asm/thread_info.h> | ||
12 | |||
13 | /* | 10 | /* |
14 | * This is the main variant and is called by C code. GCC's -pg option | 11 | * This is the main variant and is called by C code. GCC's -pg option |
15 | * automatically instruments every C function with a call to this. | 12 | * automatically instruments every C function with a call to this. |
16 | */ | 13 | */ |
17 | 14 | ||
18 | #ifdef CONFIG_STACK_DEBUG | ||
19 | |||
20 | #define OVSTACKSIZE 4096 /* lets hope this is enough */ | ||
21 | |||
22 | .data | ||
23 | .align 8 | ||
24 | panicstring: | ||
25 | .asciz "Stack overflow\n" | ||
26 | .align 8 | ||
27 | ovstack: | ||
28 | .skip OVSTACKSIZE | ||
29 | #endif | ||
30 | .text | 15 | .text |
31 | .align 32 | 16 | .align 32 |
32 | .globl _mcount | 17 | .globl _mcount |
@@ -35,84 +20,48 @@ ovstack: | |||
35 | .type mcount,#function | 20 | .type mcount,#function |
36 | _mcount: | 21 | _mcount: |
37 | mcount: | 22 | mcount: |
38 | #ifdef CONFIG_STACK_DEBUG | ||
39 | /* | ||
40 | * Check whether %sp is dangerously low. | ||
41 | */ | ||
42 | ldub [%g6 + TI_FPDEPTH], %g1 | ||
43 | srl %g1, 1, %g3 | ||
44 | add %g3, 1, %g3 | ||
45 | sllx %g3, 8, %g3 ! each fpregs frame is 256b | ||
46 | add %g3, 192, %g3 | ||
47 | add %g6, %g3, %g3 ! where does task_struct+frame end? | ||
48 | sub %g3, STACK_BIAS, %g3 | ||
49 | cmp %sp, %g3 | ||
50 | bg,pt %xcc, 1f | ||
51 | nop | ||
52 | lduh [%g6 + TI_CPU], %g1 | ||
53 | sethi %hi(hardirq_stack), %g3 | ||
54 | or %g3, %lo(hardirq_stack), %g3 | ||
55 | sllx %g1, 3, %g1 | ||
56 | ldx [%g3 + %g1], %g7 | ||
57 | sub %g7, STACK_BIAS, %g7 | ||
58 | cmp %sp, %g7 | ||
59 | bleu,pt %xcc, 2f | ||
60 | sethi %hi(THREAD_SIZE), %g3 | ||
61 | add %g7, %g3, %g7 | ||
62 | cmp %sp, %g7 | ||
63 | blu,pn %xcc, 1f | ||
64 | 2: sethi %hi(softirq_stack), %g3 | ||
65 | or %g3, %lo(softirq_stack), %g3 | ||
66 | ldx [%g3 + %g1], %g7 | ||
67 | sub %g7, STACK_BIAS, %g7 | ||
68 | cmp %sp, %g7 | ||
69 | bleu,pt %xcc, 3f | ||
70 | sethi %hi(THREAD_SIZE), %g3 | ||
71 | add %g7, %g3, %g7 | ||
72 | cmp %sp, %g7 | ||
73 | blu,pn %xcc, 1f | ||
74 | nop | ||
75 | /* If we are already on ovstack, don't hop onto it | ||
76 | * again, we are already trying to output the stack overflow | ||
77 | * message. | ||
78 | */ | ||
79 | 3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough | ||
80 | or %g7, %lo(ovstack), %g7 | ||
81 | add %g7, OVSTACKSIZE, %g3 | ||
82 | sub %g3, STACK_BIAS + 192, %g3 | ||
83 | sub %g7, STACK_BIAS, %g7 | ||
84 | cmp %sp, %g7 | ||
85 | blu,pn %xcc, 2f | ||
86 | cmp %sp, %g3 | ||
87 | bleu,pn %xcc, 1f | ||
88 | nop | ||
89 | 2: mov %g3, %sp | ||
90 | sethi %hi(panicstring), %g3 | ||
91 | call prom_printf | ||
92 | or %g3, %lo(panicstring), %o0 | ||
93 | call prom_halt | ||
94 | nop | ||
95 | 1: | ||
96 | #endif | ||
97 | #ifdef CONFIG_FUNCTION_TRACER | 23 | #ifdef CONFIG_FUNCTION_TRACER |
98 | #ifdef CONFIG_DYNAMIC_FTRACE | 24 | #ifdef CONFIG_DYNAMIC_FTRACE |
99 | mov %o7, %o0 | 25 | /* Do nothing, the retl/nop below is all we need. */ |
100 | .globl mcount_call | ||
101 | mcount_call: | ||
102 | call ftrace_stub | ||
103 | mov %o0, %o7 | ||
104 | #else | 26 | #else |
105 | sethi %hi(ftrace_trace_function), %g1 | 27 | sethi %hi(function_trace_stop), %g1 |
28 | lduw [%g1 + %lo(function_trace_stop)], %g2 | ||
29 | brnz,pn %g2, 2f | ||
30 | sethi %hi(ftrace_trace_function), %g1 | ||
106 | sethi %hi(ftrace_stub), %g2 | 31 | sethi %hi(ftrace_stub), %g2 |
107 | ldx [%g1 + %lo(ftrace_trace_function)], %g1 | 32 | ldx [%g1 + %lo(ftrace_trace_function)], %g1 |
108 | or %g2, %lo(ftrace_stub), %g2 | 33 | or %g2, %lo(ftrace_stub), %g2 |
109 | cmp %g1, %g2 | 34 | cmp %g1, %g2 |
110 | be,pn %icc, 1f | 35 | be,pn %icc, 1f |
111 | mov %i7, %o1 | 36 | mov %i7, %g3 |
112 | jmpl %g1, %g0 | 37 | save %sp, -176, %sp |
113 | mov %o7, %o0 | 38 | mov %g3, %o1 |
39 | jmpl %g1, %o7 | ||
40 | mov %i7, %o0 | ||
41 | ret | ||
42 | restore | ||
114 | /* not reached */ | 43 | /* not reached */ |
115 | 1: | 44 | 1: |
45 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
46 | sethi %hi(ftrace_graph_return), %g1 | ||
47 | ldx [%g1 + %lo(ftrace_graph_return)], %g3 | ||
48 | cmp %g2, %g3 | ||
49 | bne,pn %xcc, 5f | ||
50 | sethi %hi(ftrace_graph_entry_stub), %g2 | ||
51 | sethi %hi(ftrace_graph_entry), %g1 | ||
52 | or %g2, %lo(ftrace_graph_entry_stub), %g2 | ||
53 | ldx [%g1 + %lo(ftrace_graph_entry)], %g1 | ||
54 | cmp %g1, %g2 | ||
55 | be,pt %xcc, 2f | ||
56 | nop | ||
57 | 5: mov %i7, %g2 | ||
58 | mov %fp, %g3 | ||
59 | save %sp, -176, %sp | ||
60 | mov %g2, %l0 | ||
61 | ba,pt %xcc, ftrace_graph_caller | ||
62 | mov %g3, %l1 | ||
63 | #endif | ||
64 | 2: | ||
116 | #endif | 65 | #endif |
117 | #endif | 66 | #endif |
118 | retl | 67 | retl |
@@ -131,14 +80,50 @@ ftrace_stub: | |||
131 | .globl ftrace_caller | 80 | .globl ftrace_caller |
132 | .type ftrace_caller,#function | 81 | .type ftrace_caller,#function |
133 | ftrace_caller: | 82 | ftrace_caller: |
134 | mov %i7, %o1 | 83 | sethi %hi(function_trace_stop), %g1 |
135 | mov %o7, %o0 | 84 | mov %i7, %g2 |
85 | lduw [%g1 + %lo(function_trace_stop)], %g1 | ||
86 | brnz,pn %g1, ftrace_stub | ||
87 | mov %fp, %g3 | ||
88 | save %sp, -176, %sp | ||
89 | mov %g2, %o1 | ||
90 | mov %g2, %l0 | ||
91 | mov %g3, %l1 | ||
136 | .globl ftrace_call | 92 | .globl ftrace_call |
137 | ftrace_call: | 93 | ftrace_call: |
138 | call ftrace_stub | 94 | call ftrace_stub |
139 | mov %o0, %o7 | 95 | mov %i7, %o0 |
140 | retl | 96 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
97 | .globl ftrace_graph_call | ||
98 | ftrace_graph_call: | ||
99 | call ftrace_stub | ||
141 | nop | 100 | nop |
101 | #endif | ||
102 | ret | ||
103 | restore | ||
104 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
105 | .size ftrace_graph_call,.-ftrace_graph_call | ||
106 | #endif | ||
107 | .size ftrace_call,.-ftrace_call | ||
142 | .size ftrace_caller,.-ftrace_caller | 108 | .size ftrace_caller,.-ftrace_caller |
143 | #endif | 109 | #endif |
144 | #endif | 110 | #endif |
111 | |||
112 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
113 | ENTRY(ftrace_graph_caller) | ||
114 | mov %l0, %o0 | ||
115 | mov %i7, %o1 | ||
116 | call prepare_ftrace_return | ||
117 | mov %l1, %o2 | ||
118 | ret | ||
119 | restore %o0, -8, %i7 | ||
120 | END(ftrace_graph_caller) | ||
121 | |||
122 | ENTRY(return_to_handler) | ||
123 | save %sp, -176, %sp | ||
124 | call ftrace_return_to_handler | ||
125 | mov %fp, %o0 | ||
126 | jmpl %o0 + 8, %g0 | ||
127 | restore | ||
128 | END(return_to_handler) | ||
129 | #endif | ||
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 59b4556a5b92..e790bc1fbfa3 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -626,7 +626,7 @@ ia32_sys_call_table: | |||
626 | .quad stub32_sigreturn | 626 | .quad stub32_sigreturn |
627 | .quad stub32_clone /* 120 */ | 627 | .quad stub32_clone /* 120 */ |
628 | .quad sys_setdomainname | 628 | .quad sys_setdomainname |
629 | .quad sys_uname | 629 | .quad sys_newuname |
630 | .quad sys_modify_ldt | 630 | .quad sys_modify_ldt |
631 | .quad compat_sys_adjtimex | 631 | .quad compat_sys_adjtimex |
632 | .quad sys32_mprotect /* 125 */ | 632 | .quad sys32_mprotect /* 125 */ |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index ba19ad4c47d0..86a0ff0aeac7 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define _ASM_X86_AMD_IOMMU_TYPES_H | 21 | #define _ASM_X86_AMD_IOMMU_TYPES_H |
22 | 22 | ||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/mutex.h> | ||
24 | #include <linux/list.h> | 25 | #include <linux/list.h> |
25 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
26 | 27 | ||
@@ -140,6 +141,7 @@ | |||
140 | 141 | ||
141 | /* constants to configure the command buffer */ | 142 | /* constants to configure the command buffer */ |
142 | #define CMD_BUFFER_SIZE 8192 | 143 | #define CMD_BUFFER_SIZE 8192 |
144 | #define CMD_BUFFER_UNINITIALIZED 1 | ||
143 | #define CMD_BUFFER_ENTRIES 512 | 145 | #define CMD_BUFFER_ENTRIES 512 |
144 | #define MMIO_CMD_SIZE_SHIFT 56 | 146 | #define MMIO_CMD_SIZE_SHIFT 56 |
145 | #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT) | 147 | #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT) |
@@ -237,6 +239,7 @@ struct protection_domain { | |||
237 | struct list_head list; /* for list of all protection domains */ | 239 | struct list_head list; /* for list of all protection domains */ |
238 | struct list_head dev_list; /* List of all devices in this domain */ | 240 | struct list_head dev_list; /* List of all devices in this domain */ |
239 | spinlock_t lock; /* mostly used to lock the page table*/ | 241 | spinlock_t lock; /* mostly used to lock the page table*/ |
242 | struct mutex api_lock; /* protect page tables in the iommu-api path */ | ||
240 | u16 id; /* the domain id written to the device table */ | 243 | u16 id; /* the domain id written to the device table */ |
241 | int mode; /* paging mode (0-6 levels) */ | 244 | int mode; /* paging mode (0-6 levels) */ |
242 | u64 *pt_root; /* page table root pointer */ | 245 | u64 *pt_root; /* page table root pointer */ |
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index f46b79f6c16c..ff90055c7f0b 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define __KVM_HAVE_PIT_STATE2 | 21 | #define __KVM_HAVE_PIT_STATE2 |
22 | #define __KVM_HAVE_XEN_HVM | 22 | #define __KVM_HAVE_XEN_HVM |
23 | #define __KVM_HAVE_VCPU_EVENTS | 23 | #define __KVM_HAVE_VCPU_EVENTS |
24 | #define __KVM_HAVE_DEBUGREGS | ||
24 | 25 | ||
25 | /* Architectural interrupt line count. */ | 26 | /* Architectural interrupt line count. */ |
26 | #define KVM_NR_INTERRUPTS 256 | 27 | #define KVM_NR_INTERRUPTS 256 |
@@ -257,6 +258,11 @@ struct kvm_reinject_control { | |||
257 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ | 258 | /* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */ |
258 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 | 259 | #define KVM_VCPUEVENT_VALID_NMI_PENDING 0x00000001 |
259 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 | 260 | #define KVM_VCPUEVENT_VALID_SIPI_VECTOR 0x00000002 |
261 | #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 | ||
262 | |||
263 | /* Interrupt shadow states */ | ||
264 | #define KVM_X86_SHADOW_INT_MOV_SS 0x01 | ||
265 | #define KVM_X86_SHADOW_INT_STI 0x02 | ||
260 | 266 | ||
261 | /* for KVM_GET/SET_VCPU_EVENTS */ | 267 | /* for KVM_GET/SET_VCPU_EVENTS */ |
262 | struct kvm_vcpu_events { | 268 | struct kvm_vcpu_events { |
@@ -271,7 +277,7 @@ struct kvm_vcpu_events { | |||
271 | __u8 injected; | 277 | __u8 injected; |
272 | __u8 nr; | 278 | __u8 nr; |
273 | __u8 soft; | 279 | __u8 soft; |
274 | __u8 pad; | 280 | __u8 shadow; |
275 | } interrupt; | 281 | } interrupt; |
276 | struct { | 282 | struct { |
277 | __u8 injected; | 283 | __u8 injected; |
@@ -284,4 +290,13 @@ struct kvm_vcpu_events { | |||
284 | __u32 reserved[10]; | 290 | __u32 reserved[10]; |
285 | }; | 291 | }; |
286 | 292 | ||
293 | /* for KVM_GET/SET_DEBUGREGS */ | ||
294 | struct kvm_debugregs { | ||
295 | __u64 db[4]; | ||
296 | __u64 dr6; | ||
297 | __u64 dr7; | ||
298 | __u64 flags; | ||
299 | __u64 reserved[9]; | ||
300 | }; | ||
301 | |||
287 | #endif /* _ASM_X86_KVM_H */ | 302 | #endif /* _ASM_X86_KVM_H */ |
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 7a6f54fa13ba..0b2729bf2070 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef _ASM_X86_KVM_X86_EMULATE_H | 11 | #ifndef _ASM_X86_KVM_X86_EMULATE_H |
12 | #define _ASM_X86_KVM_X86_EMULATE_H | 12 | #define _ASM_X86_KVM_X86_EMULATE_H |
13 | 13 | ||
14 | #include <asm/desc_defs.h> | ||
15 | |||
14 | struct x86_emulate_ctxt; | 16 | struct x86_emulate_ctxt; |
15 | 17 | ||
16 | /* | 18 | /* |
@@ -63,6 +65,15 @@ struct x86_emulate_ops { | |||
63 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); | 65 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); |
64 | 66 | ||
65 | /* | 67 | /* |
68 | * write_std: Write bytes of standard (non-emulated/special) memory. | ||
69 | * Used for descriptor writing. | ||
70 | * @addr: [IN ] Linear address to which to write. | ||
71 | * @val: [OUT] Value write to memory, zero-extended to 'u_long'. | ||
72 | * @bytes: [IN ] Number of bytes to write to memory. | ||
73 | */ | ||
74 | int (*write_std)(unsigned long addr, void *val, | ||
75 | unsigned int bytes, struct kvm_vcpu *vcpu, u32 *error); | ||
76 | /* | ||
66 | * fetch: Read bytes of standard (non-emulated/special) memory. | 77 | * fetch: Read bytes of standard (non-emulated/special) memory. |
67 | * Used for instruction fetch. | 78 | * Used for instruction fetch. |
68 | * @addr: [IN ] Linear address from which to read. | 79 | * @addr: [IN ] Linear address from which to read. |
@@ -109,6 +120,23 @@ struct x86_emulate_ops { | |||
109 | unsigned int bytes, | 120 | unsigned int bytes, |
110 | struct kvm_vcpu *vcpu); | 121 | struct kvm_vcpu *vcpu); |
111 | 122 | ||
123 | int (*pio_in_emulated)(int size, unsigned short port, void *val, | ||
124 | unsigned int count, struct kvm_vcpu *vcpu); | ||
125 | |||
126 | int (*pio_out_emulated)(int size, unsigned short port, const void *val, | ||
127 | unsigned int count, struct kvm_vcpu *vcpu); | ||
128 | |||
129 | bool (*get_cached_descriptor)(struct desc_struct *desc, | ||
130 | int seg, struct kvm_vcpu *vcpu); | ||
131 | void (*set_cached_descriptor)(struct desc_struct *desc, | ||
132 | int seg, struct kvm_vcpu *vcpu); | ||
133 | u16 (*get_segment_selector)(int seg, struct kvm_vcpu *vcpu); | ||
134 | void (*set_segment_selector)(u16 sel, int seg, struct kvm_vcpu *vcpu); | ||
135 | void (*get_gdt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu); | ||
136 | ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); | ||
137 | void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); | ||
138 | int (*cpl)(struct kvm_vcpu *vcpu); | ||
139 | void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); | ||
112 | }; | 140 | }; |
113 | 141 | ||
114 | /* Type, address-of, and value of an instruction's operand. */ | 142 | /* Type, address-of, and value of an instruction's operand. */ |
@@ -124,6 +152,12 @@ struct fetch_cache { | |||
124 | unsigned long end; | 152 | unsigned long end; |
125 | }; | 153 | }; |
126 | 154 | ||
155 | struct read_cache { | ||
156 | u8 data[1024]; | ||
157 | unsigned long pos; | ||
158 | unsigned long end; | ||
159 | }; | ||
160 | |||
127 | struct decode_cache { | 161 | struct decode_cache { |
128 | u8 twobyte; | 162 | u8 twobyte; |
129 | u8 b; | 163 | u8 b; |
@@ -139,7 +173,7 @@ struct decode_cache { | |||
139 | u8 seg_override; | 173 | u8 seg_override; |
140 | unsigned int d; | 174 | unsigned int d; |
141 | unsigned long regs[NR_VCPU_REGS]; | 175 | unsigned long regs[NR_VCPU_REGS]; |
142 | unsigned long eip, eip_orig; | 176 | unsigned long eip; |
143 | /* modrm */ | 177 | /* modrm */ |
144 | u8 modrm; | 178 | u8 modrm; |
145 | u8 modrm_mod; | 179 | u8 modrm_mod; |
@@ -151,16 +185,15 @@ struct decode_cache { | |||
151 | void *modrm_ptr; | 185 | void *modrm_ptr; |
152 | unsigned long modrm_val; | 186 | unsigned long modrm_val; |
153 | struct fetch_cache fetch; | 187 | struct fetch_cache fetch; |
188 | struct read_cache io_read; | ||
154 | }; | 189 | }; |
155 | 190 | ||
156 | #define X86_SHADOW_INT_MOV_SS 1 | ||
157 | #define X86_SHADOW_INT_STI 2 | ||
158 | |||
159 | struct x86_emulate_ctxt { | 191 | struct x86_emulate_ctxt { |
160 | /* Register state before/after emulation. */ | 192 | /* Register state before/after emulation. */ |
161 | struct kvm_vcpu *vcpu; | 193 | struct kvm_vcpu *vcpu; |
162 | 194 | ||
163 | unsigned long eflags; | 195 | unsigned long eflags; |
196 | unsigned long eip; /* eip before instruction emulation */ | ||
164 | /* Emulated execution mode, represented by an X86EMUL_MODE value. */ | 197 | /* Emulated execution mode, represented by an X86EMUL_MODE value. */ |
165 | int mode; | 198 | int mode; |
166 | u32 cs_base; | 199 | u32 cs_base; |
@@ -168,6 +201,7 @@ struct x86_emulate_ctxt { | |||
168 | /* interruptibility state, as a result of execution of STI or MOV SS */ | 201 | /* interruptibility state, as a result of execution of STI or MOV SS */ |
169 | int interruptibility; | 202 | int interruptibility; |
170 | 203 | ||
204 | bool restart; /* restart string instruction after writeback */ | ||
171 | /* decode cache */ | 205 | /* decode cache */ |
172 | struct decode_cache decode; | 206 | struct decode_cache decode; |
173 | }; | 207 | }; |
@@ -194,5 +228,9 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, | |||
194 | struct x86_emulate_ops *ops); | 228 | struct x86_emulate_ops *ops); |
195 | int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, | 229 | int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, |
196 | struct x86_emulate_ops *ops); | 230 | struct x86_emulate_ops *ops); |
231 | int emulator_task_switch(struct x86_emulate_ctxt *ctxt, | ||
232 | struct x86_emulate_ops *ops, | ||
233 | u16 tss_selector, int reason, | ||
234 | bool has_error_code, u32 error_code); | ||
197 | 235 | ||
198 | #endif /* _ASM_X86_KVM_X86_EMULATE_H */ | 236 | #endif /* _ASM_X86_KVM_X86_EMULATE_H */ |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 06d9e79ca37d..3c31c5ad37ab 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -171,8 +171,8 @@ struct kvm_pte_chain { | |||
171 | union kvm_mmu_page_role { | 171 | union kvm_mmu_page_role { |
172 | unsigned word; | 172 | unsigned word; |
173 | struct { | 173 | struct { |
174 | unsigned glevels:4; | ||
175 | unsigned level:4; | 174 | unsigned level:4; |
175 | unsigned cr4_pae:1; | ||
176 | unsigned quadrant:2; | 176 | unsigned quadrant:2; |
177 | unsigned pad_for_nice_hex_output:6; | 177 | unsigned pad_for_nice_hex_output:6; |
178 | unsigned direct:1; | 178 | unsigned direct:1; |
@@ -187,8 +187,6 @@ struct kvm_mmu_page { | |||
187 | struct list_head link; | 187 | struct list_head link; |
188 | struct hlist_node hash_link; | 188 | struct hlist_node hash_link; |
189 | 189 | ||
190 | struct list_head oos_link; | ||
191 | |||
192 | /* | 190 | /* |
193 | * The following two entries are used to key the shadow page in the | 191 | * The following two entries are used to key the shadow page in the |
194 | * hash table. | 192 | * hash table. |
@@ -204,9 +202,9 @@ struct kvm_mmu_page { | |||
204 | * in this shadow page. | 202 | * in this shadow page. |
205 | */ | 203 | */ |
206 | DECLARE_BITMAP(slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); | 204 | DECLARE_BITMAP(slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); |
207 | int multimapped; /* More than one parent_pte? */ | 205 | bool multimapped; /* More than one parent_pte? */ |
208 | int root_count; /* Currently serving as active root */ | ||
209 | bool unsync; | 206 | bool unsync; |
207 | int root_count; /* Currently serving as active root */ | ||
210 | unsigned int unsync_children; | 208 | unsigned int unsync_children; |
211 | union { | 209 | union { |
212 | u64 *parent_pte; /* !multimapped */ | 210 | u64 *parent_pte; /* !multimapped */ |
@@ -224,14 +222,9 @@ struct kvm_pv_mmu_op_buffer { | |||
224 | 222 | ||
225 | struct kvm_pio_request { | 223 | struct kvm_pio_request { |
226 | unsigned long count; | 224 | unsigned long count; |
227 | int cur_count; | ||
228 | gva_t guest_gva; | ||
229 | int in; | 225 | int in; |
230 | int port; | 226 | int port; |
231 | int size; | 227 | int size; |
232 | int string; | ||
233 | int down; | ||
234 | int rep; | ||
235 | }; | 228 | }; |
236 | 229 | ||
237 | /* | 230 | /* |
@@ -362,8 +355,8 @@ struct kvm_vcpu_arch { | |||
362 | u64 *mce_banks; | 355 | u64 *mce_banks; |
363 | 356 | ||
364 | /* used for guest single stepping over the given code position */ | 357 | /* used for guest single stepping over the given code position */ |
365 | u16 singlestep_cs; | ||
366 | unsigned long singlestep_rip; | 358 | unsigned long singlestep_rip; |
359 | |||
367 | /* fields used by HYPER-V emulation */ | 360 | /* fields used by HYPER-V emulation */ |
368 | u64 hv_vapic; | 361 | u64 hv_vapic; |
369 | }; | 362 | }; |
@@ -389,6 +382,7 @@ struct kvm_arch { | |||
389 | unsigned int n_free_mmu_pages; | 382 | unsigned int n_free_mmu_pages; |
390 | unsigned int n_requested_mmu_pages; | 383 | unsigned int n_requested_mmu_pages; |
391 | unsigned int n_alloc_mmu_pages; | 384 | unsigned int n_alloc_mmu_pages; |
385 | atomic_t invlpg_counter; | ||
392 | struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; | 386 | struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; |
393 | /* | 387 | /* |
394 | * Hash table of struct kvm_mmu_page. | 388 | * Hash table of struct kvm_mmu_page. |
@@ -461,11 +455,6 @@ struct kvm_vcpu_stat { | |||
461 | u32 nmi_injections; | 455 | u32 nmi_injections; |
462 | }; | 456 | }; |
463 | 457 | ||
464 | struct descriptor_table { | ||
465 | u16 limit; | ||
466 | unsigned long base; | ||
467 | } __attribute__((packed)); | ||
468 | |||
469 | struct kvm_x86_ops { | 458 | struct kvm_x86_ops { |
470 | int (*cpu_has_kvm_support)(void); /* __init */ | 459 | int (*cpu_has_kvm_support)(void); /* __init */ |
471 | int (*disabled_by_bios)(void); /* __init */ | 460 | int (*disabled_by_bios)(void); /* __init */ |
@@ -503,12 +492,11 @@ struct kvm_x86_ops { | |||
503 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); | 492 | void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); |
504 | void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); | 493 | void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); |
505 | void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); | 494 | void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); |
506 | void (*get_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); | 495 | void (*get_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
507 | void (*set_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); | 496 | void (*set_idt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
508 | void (*get_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); | 497 | void (*get_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
509 | void (*set_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt); | 498 | void (*set_gdt)(struct kvm_vcpu *vcpu, struct desc_ptr *dt); |
510 | int (*get_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long *dest); | 499 | void (*set_dr7)(struct kvm_vcpu *vcpu, unsigned long value); |
511 | int (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value); | ||
512 | void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); | 500 | void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); |
513 | unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); | 501 | unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); |
514 | void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); | 502 | void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); |
@@ -587,23 +575,14 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
587 | void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context); | 575 | void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context); |
588 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 576 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
589 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 577 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
590 | void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, | ||
591 | unsigned long *rflags); | ||
592 | 578 | ||
593 | unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); | ||
594 | void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, | ||
595 | unsigned long *rflags); | ||
596 | void kvm_enable_efer_bits(u64); | 579 | void kvm_enable_efer_bits(u64); |
597 | int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); | 580 | int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); |
598 | int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); | 581 | int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); |
599 | 582 | ||
600 | struct x86_emulate_ctxt; | 583 | struct x86_emulate_ctxt; |
601 | 584 | ||
602 | int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, | 585 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port); |
603 | int size, unsigned port); | ||
604 | int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, | ||
605 | int size, unsigned long count, int down, | ||
606 | gva_t address, int rep, unsigned port); | ||
607 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); | 586 | void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); |
608 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); | 587 | int kvm_emulate_halt(struct kvm_vcpu *vcpu); |
609 | int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); | 588 | int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); |
@@ -616,12 +595,15 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, | |||
616 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); | 595 | void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); |
617 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); | 596 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg); |
618 | 597 | ||
619 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason); | 598 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, |
599 | bool has_error_code, u32 error_code); | ||
620 | 600 | ||
621 | void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); | 601 | void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); |
622 | void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); | 602 | void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); |
623 | void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); | 603 | void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); |
624 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); | 604 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); |
605 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val); | ||
606 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val); | ||
625 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); | 607 | unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); |
626 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); | 608 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw); |
627 | void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l); | 609 | void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l); |
@@ -649,8 +631,6 @@ int emulator_write_emulated(unsigned long addr, | |||
649 | unsigned int bytes, | 631 | unsigned int bytes, |
650 | struct kvm_vcpu *vcpu); | 632 | struct kvm_vcpu *vcpu); |
651 | 633 | ||
652 | unsigned long segment_base(u16 selector); | ||
653 | |||
654 | void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu); | 634 | void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu); |
655 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | 635 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, |
656 | const u8 *new, int bytes, | 636 | const u8 *new, int bytes, |
@@ -675,7 +655,6 @@ void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); | |||
675 | void kvm_enable_tdp(void); | 655 | void kvm_enable_tdp(void); |
676 | void kvm_disable_tdp(void); | 656 | void kvm_disable_tdp(void); |
677 | 657 | ||
678 | int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); | ||
679 | int complete_pio(struct kvm_vcpu *vcpu); | 658 | int complete_pio(struct kvm_vcpu *vcpu); |
680 | bool kvm_check_iopl(struct kvm_vcpu *vcpu); | 659 | bool kvm_check_iopl(struct kvm_vcpu *vcpu); |
681 | 660 | ||
@@ -724,23 +703,6 @@ static inline void kvm_load_ldt(u16 sel) | |||
724 | asm("lldt %0" : : "rm"(sel)); | 703 | asm("lldt %0" : : "rm"(sel)); |
725 | } | 704 | } |
726 | 705 | ||
727 | static inline void kvm_get_idt(struct descriptor_table *table) | ||
728 | { | ||
729 | asm("sidt %0" : "=m"(*table)); | ||
730 | } | ||
731 | |||
732 | static inline void kvm_get_gdt(struct descriptor_table *table) | ||
733 | { | ||
734 | asm("sgdt %0" : "=m"(*table)); | ||
735 | } | ||
736 | |||
737 | static inline unsigned long kvm_read_tr_base(void) | ||
738 | { | ||
739 | u16 tr; | ||
740 | asm("str %0" : "=g"(tr)); | ||
741 | return segment_base(tr); | ||
742 | } | ||
743 | |||
744 | #ifdef CONFIG_X86_64 | 706 | #ifdef CONFIG_X86_64 |
745 | static inline unsigned long read_msr(unsigned long msr) | 707 | static inline unsigned long read_msr(unsigned long msr) |
746 | { | 708 | { |
@@ -826,4 +788,6 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | |||
826 | void kvm_define_shared_msr(unsigned index, u32 msr); | 788 | void kvm_define_shared_msr(unsigned index, u32 msr); |
827 | void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); | 789 | void kvm_set_shared_msr(unsigned index, u64 val, u64 mask); |
828 | 790 | ||
791 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip); | ||
792 | |||
829 | #endif /* _ASM_X86_KVM_HOST_H */ | 793 | #endif /* _ASM_X86_KVM_HOST_H */ |
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index ba0eed8aa1a6..b60f2924c413 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h | |||
@@ -28,22 +28,39 @@ | |||
28 | 28 | ||
29 | #ifndef __ASSEMBLY__ | 29 | #ifndef __ASSEMBLY__ |
30 | #include <asm/hw_irq.h> | 30 | #include <asm/hw_irq.h> |
31 | #include <asm/kvm_para.h> | ||
32 | 31 | ||
33 | /*G:030 | 32 | /*G:030 |
34 | * But first, how does our Guest contact the Host to ask for privileged | 33 | * But first, how does our Guest contact the Host to ask for privileged |
35 | * operations? There are two ways: the direct way is to make a "hypercall", | 34 | * operations? There are two ways: the direct way is to make a "hypercall", |
36 | * to make requests of the Host Itself. | 35 | * to make requests of the Host Itself. |
37 | * | 36 | * |
38 | * We use the KVM hypercall mechanism, though completely different hypercall | 37 | * Our hypercall mechanism uses the highest unused trap code (traps 32 and |
39 | * numbers. Seventeen hypercalls are available: the hypercall number is put in | 38 | * above are used by real hardware interrupts). Seventeen hypercalls are |
40 | * the %eax register, and the arguments (when required) are placed in %ebx, | 39 | * available: the hypercall number is put in the %eax register, and the |
41 | * %ecx, %edx and %esi. If a return value makes sense, it's returned in %eax. | 40 | * arguments (when required) are placed in %ebx, %ecx, %edx and %esi. |
41 | * If a return value makes sense, it's returned in %eax. | ||
42 | * | 42 | * |
43 | * Grossly invalid calls result in Sudden Death at the hands of the vengeful | 43 | * Grossly invalid calls result in Sudden Death at the hands of the vengeful |
44 | * Host, rather than returning failure. This reflects Winston Churchill's | 44 | * Host, rather than returning failure. This reflects Winston Churchill's |
45 | * definition of a gentleman: "someone who is only rude intentionally". | 45 | * definition of a gentleman: "someone who is only rude intentionally". |
46 | :*/ | 46 | */ |
47 | static inline unsigned long | ||
48 | hcall(unsigned long call, | ||
49 | unsigned long arg1, unsigned long arg2, unsigned long arg3, | ||
50 | unsigned long arg4) | ||
51 | { | ||
52 | /* "int" is the Intel instruction to trigger a trap. */ | ||
53 | asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) | ||
54 | /* The call in %eax (aka "a") might be overwritten */ | ||
55 | : "=a"(call) | ||
56 | /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */ | ||
57 | : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) | ||
58 | /* "memory" means this might write somewhere in memory. | ||
59 | * This isn't true for all calls, but it's safe to tell | ||
60 | * gcc that it might happen so it doesn't get clever. */ | ||
61 | : "memory"); | ||
62 | return call; | ||
63 | } | ||
47 | 64 | ||
48 | /* Can't use our min() macro here: needs to be a constant */ | 65 | /* Can't use our min() macro here: needs to be a constant */ |
49 | #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) | 66 | #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) |
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 38638cd2fa4c..0e831059ac5a 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h | |||
@@ -81,7 +81,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { | |||
81 | u32 event_inj_err; | 81 | u32 event_inj_err; |
82 | u64 nested_cr3; | 82 | u64 nested_cr3; |
83 | u64 lbr_ctl; | 83 | u64 lbr_ctl; |
84 | u8 reserved_5[832]; | 84 | u64 reserved_5; |
85 | u64 next_rip; | ||
86 | u8 reserved_6[816]; | ||
85 | }; | 87 | }; |
86 | 88 | ||
87 | 89 | ||
@@ -115,6 +117,10 @@ struct __attribute__ ((__packed__)) vmcb_control_area { | |||
115 | #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) | 117 | #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) |
116 | #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) | 118 | #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) |
117 | 119 | ||
120 | #define SVM_VM_CR_VALID_MASK 0x001fULL | ||
121 | #define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL | ||
122 | #define SVM_VM_CR_SVM_DIS_MASK 0x0010ULL | ||
123 | |||
118 | struct __attribute__ ((__packed__)) vmcb_seg { | 124 | struct __attribute__ ((__packed__)) vmcb_seg { |
119 | u16 selector; | 125 | u16 selector; |
120 | u16 attrib; | 126 | u16 attrib; |
@@ -238,6 +244,7 @@ struct __attribute__ ((__packed__)) vmcb { | |||
238 | 244 | ||
239 | #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 | 245 | #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 |
240 | #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 | 246 | #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 |
247 | #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 | ||
241 | 248 | ||
242 | #define SVM_EXIT_READ_CR0 0x000 | 249 | #define SVM_EXIT_READ_CR0 0x000 |
243 | #define SVM_EXIT_READ_CR3 0x003 | 250 | #define SVM_EXIT_READ_CR3 0x003 |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index f3dadb571d9b..f854d89b7edf 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev) | |||
118 | return false; | 118 | return false; |
119 | 119 | ||
120 | /* No device or no PCI device */ | 120 | /* No device or no PCI device */ |
121 | if (!dev || dev->bus != &pci_bus_type) | 121 | if (dev->bus != &pci_bus_type) |
122 | return false; | 122 | return false; |
123 | 123 | ||
124 | devid = get_device_id(dev); | 124 | devid = get_device_id(dev); |
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
392 | u32 tail, head; | 392 | u32 tail, head; |
393 | u8 *target; | 393 | u8 *target; |
394 | 394 | ||
395 | WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED); | ||
395 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | 396 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); |
396 | target = iommu->cmd_buf + tail; | 397 | target = iommu->cmd_buf + tail; |
397 | memcpy_toio(target, cmd, sizeof(*cmd)); | 398 | memcpy_toio(target, cmd, sizeof(*cmd)); |
@@ -2186,7 +2187,7 @@ static void prealloc_protection_domains(void) | |||
2186 | struct dma_ops_domain *dma_dom; | 2187 | struct dma_ops_domain *dma_dom; |
2187 | u16 devid; | 2188 | u16 devid; |
2188 | 2189 | ||
2189 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2190 | for_each_pci_dev(dev) { |
2190 | 2191 | ||
2191 | /* Do we handle this device? */ | 2192 | /* Do we handle this device? */ |
2192 | if (!check_device(&dev->dev)) | 2193 | if (!check_device(&dev->dev)) |
@@ -2298,7 +2299,7 @@ static void cleanup_domain(struct protection_domain *domain) | |||
2298 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { | 2299 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { |
2299 | struct device *dev = dev_data->dev; | 2300 | struct device *dev = dev_data->dev; |
2300 | 2301 | ||
2301 | do_detach(dev); | 2302 | __detach_device(dev); |
2302 | atomic_set(&dev_data->bind, 0); | 2303 | atomic_set(&dev_data->bind, 0); |
2303 | } | 2304 | } |
2304 | 2305 | ||
@@ -2327,6 +2328,7 @@ static struct protection_domain *protection_domain_alloc(void) | |||
2327 | return NULL; | 2328 | return NULL; |
2328 | 2329 | ||
2329 | spin_lock_init(&domain->lock); | 2330 | spin_lock_init(&domain->lock); |
2331 | mutex_init(&domain->api_lock); | ||
2330 | domain->id = domain_id_alloc(); | 2332 | domain->id = domain_id_alloc(); |
2331 | if (!domain->id) | 2333 | if (!domain->id) |
2332 | goto out_err; | 2334 | goto out_err; |
@@ -2379,9 +2381,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) | |||
2379 | 2381 | ||
2380 | free_pagetable(domain); | 2382 | free_pagetable(domain); |
2381 | 2383 | ||
2382 | domain_id_free(domain->id); | 2384 | protection_domain_free(domain); |
2383 | |||
2384 | kfree(domain); | ||
2385 | 2385 | ||
2386 | dom->priv = NULL; | 2386 | dom->priv = NULL; |
2387 | } | 2387 | } |
@@ -2456,6 +2456,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
2456 | iova &= PAGE_MASK; | 2456 | iova &= PAGE_MASK; |
2457 | paddr &= PAGE_MASK; | 2457 | paddr &= PAGE_MASK; |
2458 | 2458 | ||
2459 | mutex_lock(&domain->api_lock); | ||
2460 | |||
2459 | for (i = 0; i < npages; ++i) { | 2461 | for (i = 0; i < npages; ++i) { |
2460 | ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); | 2462 | ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); |
2461 | if (ret) | 2463 | if (ret) |
@@ -2465,6 +2467,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
2465 | paddr += PAGE_SIZE; | 2467 | paddr += PAGE_SIZE; |
2466 | } | 2468 | } |
2467 | 2469 | ||
2470 | mutex_unlock(&domain->api_lock); | ||
2471 | |||
2468 | return 0; | 2472 | return 0; |
2469 | } | 2473 | } |
2470 | 2474 | ||
@@ -2477,12 +2481,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, | |||
2477 | 2481 | ||
2478 | iova &= PAGE_MASK; | 2482 | iova &= PAGE_MASK; |
2479 | 2483 | ||
2484 | mutex_lock(&domain->api_lock); | ||
2485 | |||
2480 | for (i = 0; i < npages; ++i) { | 2486 | for (i = 0; i < npages; ++i) { |
2481 | iommu_unmap_page(domain, iova, PM_MAP_4k); | 2487 | iommu_unmap_page(domain, iova, PM_MAP_4k); |
2482 | iova += PAGE_SIZE; | 2488 | iova += PAGE_SIZE; |
2483 | } | 2489 | } |
2484 | 2490 | ||
2485 | iommu_flush_tlb_pde(domain); | 2491 | iommu_flush_tlb_pde(domain); |
2492 | |||
2493 | mutex_unlock(&domain->api_lock); | ||
2486 | } | 2494 | } |
2487 | 2495 | ||
2488 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | 2496 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 42f5350b908f..6360abf993d4 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -138,9 +138,9 @@ int amd_iommus_present; | |||
138 | bool amd_iommu_np_cache __read_mostly; | 138 | bool amd_iommu_np_cache __read_mostly; |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Set to true if ACPI table parsing and hardware intialization went properly | 141 | * The ACPI table parsing functions set this variable on an error |
142 | */ | 142 | */ |
143 | static bool amd_iommu_initialized; | 143 | static int __initdata amd_iommu_init_err; |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * List of protection domains - used during resume | 146 | * List of protection domains - used during resume |
@@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table) | |||
391 | */ | 391 | */ |
392 | for (i = 0; i < table->length; ++i) | 392 | for (i = 0; i < table->length; ++i) |
393 | checksum += p[i]; | 393 | checksum += p[i]; |
394 | if (checksum != 0) | 394 | if (checksum != 0) { |
395 | /* ACPI table corrupt */ | 395 | /* ACPI table corrupt */ |
396 | return -ENODEV; | 396 | amd_iommu_init_err = -ENODEV; |
397 | return 0; | ||
398 | } | ||
397 | 399 | ||
398 | p += IVRS_HEADER_LENGTH; | 400 | p += IVRS_HEADER_LENGTH; |
399 | 401 | ||
@@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) | |||
436 | if (cmd_buf == NULL) | 438 | if (cmd_buf == NULL) |
437 | return NULL; | 439 | return NULL; |
438 | 440 | ||
439 | iommu->cmd_buf_size = CMD_BUFFER_SIZE; | 441 | iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED; |
440 | 442 | ||
441 | return cmd_buf; | 443 | return cmd_buf; |
442 | } | 444 | } |
@@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu) | |||
472 | &entry, sizeof(entry)); | 474 | &entry, sizeof(entry)); |
473 | 475 | ||
474 | amd_iommu_reset_cmd_buffer(iommu); | 476 | amd_iommu_reset_cmd_buffer(iommu); |
477 | iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED); | ||
475 | } | 478 | } |
476 | 479 | ||
477 | static void __init free_command_buffer(struct amd_iommu *iommu) | 480 | static void __init free_command_buffer(struct amd_iommu *iommu) |
478 | { | 481 | { |
479 | free_pages((unsigned long)iommu->cmd_buf, | 482 | free_pages((unsigned long)iommu->cmd_buf, |
480 | get_order(iommu->cmd_buf_size)); | 483 | get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED))); |
481 | } | 484 | } |
482 | 485 | ||
483 | /* allocates the memory where the IOMMU will log its events to */ | 486 | /* allocates the memory where the IOMMU will log its events to */ |
@@ -920,11 +923,16 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
920 | h->mmio_phys); | 923 | h->mmio_phys); |
921 | 924 | ||
922 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); | 925 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); |
923 | if (iommu == NULL) | 926 | if (iommu == NULL) { |
924 | return -ENOMEM; | 927 | amd_iommu_init_err = -ENOMEM; |
928 | return 0; | ||
929 | } | ||
930 | |||
925 | ret = init_iommu_one(iommu, h); | 931 | ret = init_iommu_one(iommu, h); |
926 | if (ret) | 932 | if (ret) { |
927 | return ret; | 933 | amd_iommu_init_err = ret; |
934 | return 0; | ||
935 | } | ||
928 | break; | 936 | break; |
929 | default: | 937 | default: |
930 | break; | 938 | break; |
@@ -934,8 +942,6 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
934 | } | 942 | } |
935 | WARN_ON(p != end); | 943 | WARN_ON(p != end); |
936 | 944 | ||
937 | amd_iommu_initialized = true; | ||
938 | |||
939 | return 0; | 945 | return 0; |
940 | } | 946 | } |
941 | 947 | ||
@@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void) | |||
1211 | if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) | 1217 | if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) |
1212 | return -ENODEV; | 1218 | return -ENODEV; |
1213 | 1219 | ||
1220 | ret = amd_iommu_init_err; | ||
1221 | if (ret) | ||
1222 | goto out; | ||
1223 | |||
1214 | dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); | 1224 | dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); |
1215 | alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); | 1225 | alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); |
1216 | rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); | 1226 | rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); |
@@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void) | |||
1270 | if (acpi_table_parse("IVRS", init_iommu_all) != 0) | 1280 | if (acpi_table_parse("IVRS", init_iommu_all) != 0) |
1271 | goto free; | 1281 | goto free; |
1272 | 1282 | ||
1273 | if (!amd_iommu_initialized) | 1283 | if (amd_iommu_init_err) { |
1284 | ret = amd_iommu_init_err; | ||
1274 | goto free; | 1285 | goto free; |
1286 | } | ||
1275 | 1287 | ||
1276 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) | 1288 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) |
1277 | goto free; | 1289 | goto free; |
1278 | 1290 | ||
1291 | if (amd_iommu_init_err) { | ||
1292 | ret = amd_iommu_init_err; | ||
1293 | goto free; | ||
1294 | } | ||
1295 | |||
1279 | ret = sysdev_class_register(&amd_iommu_sysdev_class); | 1296 | ret = sysdev_class_register(&amd_iommu_sysdev_class); |
1280 | if (ret) | 1297 | if (ret) |
1281 | goto free; | 1298 | goto free; |
@@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void) | |||
1288 | if (ret) | 1305 | if (ret) |
1289 | goto free; | 1306 | goto free; |
1290 | 1307 | ||
1308 | enable_iommus(); | ||
1309 | |||
1291 | if (iommu_pass_through) | 1310 | if (iommu_pass_through) |
1292 | ret = amd_iommu_init_passthrough(); | 1311 | ret = amd_iommu_init_passthrough(); |
1293 | else | 1312 | else |
@@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void) | |||
1300 | 1319 | ||
1301 | amd_iommu_init_notifier(); | 1320 | amd_iommu_init_notifier(); |
1302 | 1321 | ||
1303 | enable_iommus(); | ||
1304 | |||
1305 | if (iommu_pass_through) | 1322 | if (iommu_pass_through) |
1306 | goto out; | 1323 | goto out; |
1307 | 1324 | ||
@@ -1315,6 +1332,7 @@ out: | |||
1315 | return ret; | 1332 | return ret; |
1316 | 1333 | ||
1317 | free: | 1334 | free: |
1335 | disable_iommus(); | ||
1318 | 1336 | ||
1319 | amd_iommu_uninit_devices(); | 1337 | amd_iommu_uninit_devices(); |
1320 | 1338 | ||
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 3704997e8b25..b5d8b0bcf235 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c | |||
@@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void) | |||
393 | for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { | 393 | for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { |
394 | int bus; | 394 | int bus; |
395 | int dev_base, dev_limit; | 395 | int dev_base, dev_limit; |
396 | u32 ctl; | ||
396 | 397 | ||
397 | bus = bus_dev_ranges[i].bus; | 398 | bus = bus_dev_ranges[i].bus; |
398 | dev_base = bus_dev_ranges[i].dev_base; | 399 | dev_base = bus_dev_ranges[i].dev_base; |
@@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void) | |||
406 | gart_iommu_aperture = 1; | 407 | gart_iommu_aperture = 1; |
407 | x86_init.iommu.iommu_init = gart_iommu_init; | 408 | x86_init.iommu.iommu_init = gart_iommu_init; |
408 | 409 | ||
409 | aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7; | 410 | ctl = read_pci_config(bus, slot, 3, |
411 | AMD64_GARTAPERTURECTL); | ||
412 | |||
413 | /* | ||
414 | * Before we do anything else disable the GART. It may | ||
415 | * still be enabled if we boot into a crash-kernel here. | ||
416 | * Reconfiguring the GART while it is enabled could have | ||
417 | * unknown side-effects. | ||
418 | */ | ||
419 | ctl &= ~GARTEN; | ||
420 | write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl); | ||
421 | |||
422 | aper_order = (ctl >> 1) & 7; | ||
410 | aper_size = (32 * 1024 * 1024) << aper_order; | 423 | aper_size = (32 * 1024 * 1024) << aper_order; |
411 | aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; | 424 | aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; |
412 | aper_base <<= 25; | 425 | aper_base <<= 25; |
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a4849c10a77e..ebd4c51d096a 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
28 | #include <asm/reboot.h> | 28 | #include <asm/reboot.h> |
29 | #include <asm/virtext.h> | 29 | #include <asm/virtext.h> |
30 | #include <asm/x86_init.h> | ||
31 | 30 | ||
32 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) | 31 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) |
33 | 32 | ||
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs) | |||
103 | #ifdef CONFIG_HPET_TIMER | 102 | #ifdef CONFIG_HPET_TIMER |
104 | hpet_disable(); | 103 | hpet_disable(); |
105 | #endif | 104 | #endif |
106 | |||
107 | #ifdef CONFIG_X86_64 | ||
108 | x86_platform.iommu_shutdown(); | ||
109 | #endif | ||
110 | |||
111 | crash_save_cpu(regs, safe_smp_processor_id()); | 105 | crash_save_cpu(regs, safe_smp_processor_id()); |
112 | } | 106 | } |
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h index e39e77168a37..e1a93be4fd44 100644 --- a/arch/x86/kernel/dumpstack.h +++ b/arch/x86/kernel/dumpstack.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) | 14 | #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | #include <linux/uaccess.h> | ||
18 | |||
17 | extern void | 19 | extern void |
18 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 20 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
19 | unsigned long *stack, unsigned long bp, char *log_lvl); | 21 | unsigned long *stack, unsigned long bp, char *log_lvl); |
@@ -42,8 +44,10 @@ static inline unsigned long rewind_frame_pointer(int n) | |||
42 | get_bp(frame); | 44 | get_bp(frame); |
43 | 45 | ||
44 | #ifdef CONFIG_FRAME_POINTER | 46 | #ifdef CONFIG_FRAME_POINTER |
45 | while (n--) | 47 | while (n--) { |
46 | frame = frame->next_frame; | 48 | if (probe_kernel_address(&frame->next_frame, frame)) |
49 | break; | ||
50 | } | ||
47 | #endif | 51 | #endif |
48 | 52 | ||
49 | return (unsigned long)frame; | 53 | return (unsigned long)frame; |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 68cd24f9deae..0f7f130caa67 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -565,6 +565,9 @@ static void enable_gart_translations(void) | |||
565 | 565 | ||
566 | enable_gart_translation(dev, __pa(agp_gatt_table)); | 566 | enable_gart_translation(dev, __pa(agp_gatt_table)); |
567 | } | 567 | } |
568 | |||
569 | /* Flush the GART-TLB to remove stale entries */ | ||
570 | k8_flush_garts(); | ||
568 | } | 571 | } |
569 | 572 | ||
570 | /* | 573 | /* |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4dade6ac0827..5ac0bb465ed6 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/kvm_emulate.h> | 33 | #include <asm/kvm_emulate.h> |
34 | 34 | ||
35 | #include "x86.h" | 35 | #include "x86.h" |
36 | #include "tss.h" | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * Opcode effective-address decode tables. | 39 | * Opcode effective-address decode tables. |
@@ -50,6 +51,8 @@ | |||
50 | #define DstReg (2<<1) /* Register operand. */ | 51 | #define DstReg (2<<1) /* Register operand. */ |
51 | #define DstMem (3<<1) /* Memory operand. */ | 52 | #define DstMem (3<<1) /* Memory operand. */ |
52 | #define DstAcc (4<<1) /* Destination Accumulator */ | 53 | #define DstAcc (4<<1) /* Destination Accumulator */ |
54 | #define DstDI (5<<1) /* Destination is in ES:(E)DI */ | ||
55 | #define DstMem64 (6<<1) /* 64bit memory operand */ | ||
53 | #define DstMask (7<<1) | 56 | #define DstMask (7<<1) |
54 | /* Source operand type. */ | 57 | /* Source operand type. */ |
55 | #define SrcNone (0<<4) /* No source operand. */ | 58 | #define SrcNone (0<<4) /* No source operand. */ |
@@ -63,6 +66,7 @@ | |||
63 | #define SrcOne (7<<4) /* Implied '1' */ | 66 | #define SrcOne (7<<4) /* Implied '1' */ |
64 | #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ | 67 | #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ |
65 | #define SrcImmU (9<<4) /* Immediate operand, unsigned */ | 68 | #define SrcImmU (9<<4) /* Immediate operand, unsigned */ |
69 | #define SrcSI (0xa<<4) /* Source is in the DS:RSI */ | ||
66 | #define SrcMask (0xf<<4) | 70 | #define SrcMask (0xf<<4) |
67 | /* Generic ModRM decode. */ | 71 | /* Generic ModRM decode. */ |
68 | #define ModRM (1<<8) | 72 | #define ModRM (1<<8) |
@@ -85,6 +89,9 @@ | |||
85 | #define Src2ImmByte (2<<29) | 89 | #define Src2ImmByte (2<<29) |
86 | #define Src2One (3<<29) | 90 | #define Src2One (3<<29) |
87 | #define Src2Imm16 (4<<29) | 91 | #define Src2Imm16 (4<<29) |
92 | #define Src2Mem16 (5<<29) /* Used for Ep encoding. First argument has to be | ||
93 | in memory and second argument is located | ||
94 | immediately after the first one in memory. */ | ||
88 | #define Src2Mask (7<<29) | 95 | #define Src2Mask (7<<29) |
89 | 96 | ||
90 | enum { | 97 | enum { |
@@ -147,8 +154,8 @@ static u32 opcode_table[256] = { | |||
147 | 0, 0, 0, 0, | 154 | 0, 0, 0, 0, |
148 | /* 0x68 - 0x6F */ | 155 | /* 0x68 - 0x6F */ |
149 | SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, | 156 | SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0, |
150 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* insb, insw/insd */ | 157 | DstDI | ByteOp | Mov | String, DstDI | Mov | String, /* insb, insw/insd */ |
151 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, /* outsb, outsw/outsd */ | 158 | SrcSI | ByteOp | ImplicitOps | String, SrcSI | ImplicitOps | String, /* outsb, outsw/outsd */ |
152 | /* 0x70 - 0x77 */ | 159 | /* 0x70 - 0x77 */ |
153 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, | 160 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
154 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, | 161 | SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte, |
@@ -173,12 +180,12 @@ static u32 opcode_table[256] = { | |||
173 | /* 0xA0 - 0xA7 */ | 180 | /* 0xA0 - 0xA7 */ |
174 | ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, | 181 | ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs, |
175 | ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, | 182 | ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs, |
176 | ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, | 183 | ByteOp | SrcSI | DstDI | Mov | String, SrcSI | DstDI | Mov | String, |
177 | ByteOp | ImplicitOps | String, ImplicitOps | String, | 184 | ByteOp | SrcSI | DstDI | String, SrcSI | DstDI | String, |
178 | /* 0xA8 - 0xAF */ | 185 | /* 0xA8 - 0xAF */ |
179 | 0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, | 186 | 0, 0, ByteOp | DstDI | Mov | String, DstDI | Mov | String, |
180 | ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String, | 187 | ByteOp | SrcSI | DstAcc | Mov | String, SrcSI | DstAcc | Mov | String, |
181 | ByteOp | ImplicitOps | String, ImplicitOps | String, | 188 | ByteOp | DstDI | String, DstDI | String, |
182 | /* 0xB0 - 0xB7 */ | 189 | /* 0xB0 - 0xB7 */ |
183 | ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, | 190 | ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, |
184 | ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, | 191 | ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov, |
@@ -204,13 +211,13 @@ static u32 opcode_table[256] = { | |||
204 | 0, 0, 0, 0, 0, 0, 0, 0, | 211 | 0, 0, 0, 0, 0, 0, 0, 0, |
205 | /* 0xE0 - 0xE7 */ | 212 | /* 0xE0 - 0xE7 */ |
206 | 0, 0, 0, 0, | 213 | 0, 0, 0, 0, |
207 | ByteOp | SrcImmUByte, SrcImmUByte, | 214 | ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc, |
208 | ByteOp | SrcImmUByte, SrcImmUByte, | 215 | ByteOp | SrcImmUByte | DstAcc, SrcImmUByte | DstAcc, |
209 | /* 0xE8 - 0xEF */ | 216 | /* 0xE8 - 0xEF */ |
210 | SrcImm | Stack, SrcImm | ImplicitOps, | 217 | SrcImm | Stack, SrcImm | ImplicitOps, |
211 | SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps, | 218 | SrcImmU | Src2Imm16 | No64, SrcImmByte | ImplicitOps, |
212 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 219 | SrcNone | ByteOp | DstAcc, SrcNone | DstAcc, |
213 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 220 | SrcNone | ByteOp | DstAcc, SrcNone | DstAcc, |
214 | /* 0xF0 - 0xF7 */ | 221 | /* 0xF0 - 0xF7 */ |
215 | 0, 0, 0, 0, | 222 | 0, 0, 0, 0, |
216 | ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, | 223 | ImplicitOps | Priv, ImplicitOps, Group | Group3_Byte, Group | Group3, |
@@ -343,7 +350,8 @@ static u32 group_table[] = { | |||
343 | [Group5*8] = | 350 | [Group5*8] = |
344 | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, | 351 | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, |
345 | SrcMem | ModRM | Stack, 0, | 352 | SrcMem | ModRM | Stack, 0, |
346 | SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0, | 353 | SrcMem | ModRM | Stack, SrcMem | ModRM | Src2Mem16 | ImplicitOps, |
354 | SrcMem | ModRM | Stack, 0, | ||
347 | [Group7*8] = | 355 | [Group7*8] = |
348 | 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, | 356 | 0, 0, ModRM | SrcMem | Priv, ModRM | SrcMem | Priv, |
349 | SrcNone | ModRM | DstMem | Mov, 0, | 357 | SrcNone | ModRM | DstMem | Mov, 0, |
@@ -353,14 +361,14 @@ static u32 group_table[] = { | |||
353 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, | 361 | DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM | Lock, |
354 | DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, | 362 | DstMem | SrcImmByte | ModRM | Lock, DstMem | SrcImmByte | ModRM | Lock, |
355 | [Group9*8] = | 363 | [Group9*8] = |
356 | 0, ImplicitOps | ModRM | Lock, 0, 0, 0, 0, 0, 0, | 364 | 0, DstMem64 | ModRM | Lock, 0, 0, 0, 0, 0, 0, |
357 | }; | 365 | }; |
358 | 366 | ||
359 | static u32 group2_table[] = { | 367 | static u32 group2_table[] = { |
360 | [Group7*8] = | 368 | [Group7*8] = |
361 | SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM, | 369 | SrcNone | ModRM | Priv, 0, 0, SrcNone | ModRM | Priv, |
362 | SrcNone | ModRM | DstMem | Mov, 0, | 370 | SrcNone | ModRM | DstMem | Mov, 0, |
363 | SrcMem16 | ModRM | Mov, 0, | 371 | SrcMem16 | ModRM | Mov | Priv, 0, |
364 | [Group9*8] = | 372 | [Group9*8] = |
365 | 0, 0, 0, 0, 0, 0, 0, 0, | 373 | 0, 0, 0, 0, 0, 0, 0, 0, |
366 | }; | 374 | }; |
@@ -562,7 +570,7 @@ static u32 group2_table[] = { | |||
562 | #define insn_fetch(_type, _size, _eip) \ | 570 | #define insn_fetch(_type, _size, _eip) \ |
563 | ({ unsigned long _x; \ | 571 | ({ unsigned long _x; \ |
564 | rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size)); \ | 572 | rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size)); \ |
565 | if (rc != 0) \ | 573 | if (rc != X86EMUL_CONTINUE) \ |
566 | goto done; \ | 574 | goto done; \ |
567 | (_eip) += (_size); \ | 575 | (_eip) += (_size); \ |
568 | (_type)_x; \ | 576 | (_type)_x; \ |
@@ -638,40 +646,40 @@ static unsigned long ss_base(struct x86_emulate_ctxt *ctxt) | |||
638 | 646 | ||
639 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, | 647 | static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, |
640 | struct x86_emulate_ops *ops, | 648 | struct x86_emulate_ops *ops, |
641 | unsigned long linear, u8 *dest) | 649 | unsigned long eip, u8 *dest) |
642 | { | 650 | { |
643 | struct fetch_cache *fc = &ctxt->decode.fetch; | 651 | struct fetch_cache *fc = &ctxt->decode.fetch; |
644 | int rc; | 652 | int rc; |
645 | int size; | 653 | int size, cur_size; |
646 | 654 | ||
647 | if (linear < fc->start || linear >= fc->end) { | 655 | if (eip == fc->end) { |
648 | size = min(15UL, PAGE_SIZE - offset_in_page(linear)); | 656 | cur_size = fc->end - fc->start; |
649 | rc = ops->fetch(linear, fc->data, size, ctxt->vcpu, NULL); | 657 | size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip)); |
650 | if (rc) | 658 | rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size, |
659 | size, ctxt->vcpu, NULL); | ||
660 | if (rc != X86EMUL_CONTINUE) | ||
651 | return rc; | 661 | return rc; |
652 | fc->start = linear; | 662 | fc->end += size; |
653 | fc->end = linear + size; | ||
654 | } | 663 | } |
655 | *dest = fc->data[linear - fc->start]; | 664 | *dest = fc->data[eip - fc->start]; |
656 | return 0; | 665 | return X86EMUL_CONTINUE; |
657 | } | 666 | } |
658 | 667 | ||
659 | static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, | 668 | static int do_insn_fetch(struct x86_emulate_ctxt *ctxt, |
660 | struct x86_emulate_ops *ops, | 669 | struct x86_emulate_ops *ops, |
661 | unsigned long eip, void *dest, unsigned size) | 670 | unsigned long eip, void *dest, unsigned size) |
662 | { | 671 | { |
663 | int rc = 0; | 672 | int rc; |
664 | 673 | ||
665 | /* x86 instructions are limited to 15 bytes. */ | 674 | /* x86 instructions are limited to 15 bytes. */ |
666 | if (eip + size - ctxt->decode.eip_orig > 15) | 675 | if (eip + size - ctxt->eip > 15) |
667 | return X86EMUL_UNHANDLEABLE; | 676 | return X86EMUL_UNHANDLEABLE; |
668 | eip += ctxt->cs_base; | ||
669 | while (size--) { | 677 | while (size--) { |
670 | rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); | 678 | rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++); |
671 | if (rc) | 679 | if (rc != X86EMUL_CONTINUE) |
672 | return rc; | 680 | return rc; |
673 | } | 681 | } |
674 | return 0; | 682 | return X86EMUL_CONTINUE; |
675 | } | 683 | } |
676 | 684 | ||
677 | /* | 685 | /* |
@@ -702,7 +710,7 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
702 | *address = 0; | 710 | *address = 0; |
703 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, | 711 | rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2, |
704 | ctxt->vcpu, NULL); | 712 | ctxt->vcpu, NULL); |
705 | if (rc) | 713 | if (rc != X86EMUL_CONTINUE) |
706 | return rc; | 714 | return rc; |
707 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, | 715 | rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes, |
708 | ctxt->vcpu, NULL); | 716 | ctxt->vcpu, NULL); |
@@ -782,7 +790,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
782 | struct decode_cache *c = &ctxt->decode; | 790 | struct decode_cache *c = &ctxt->decode; |
783 | u8 sib; | 791 | u8 sib; |
784 | int index_reg = 0, base_reg = 0, scale; | 792 | int index_reg = 0, base_reg = 0, scale; |
785 | int rc = 0; | 793 | int rc = X86EMUL_CONTINUE; |
786 | 794 | ||
787 | if (c->rex_prefix) { | 795 | if (c->rex_prefix) { |
788 | c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */ | 796 | c->modrm_reg = (c->rex_prefix & 4) << 1; /* REX.R */ |
@@ -895,7 +903,7 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt, | |||
895 | struct x86_emulate_ops *ops) | 903 | struct x86_emulate_ops *ops) |
896 | { | 904 | { |
897 | struct decode_cache *c = &ctxt->decode; | 905 | struct decode_cache *c = &ctxt->decode; |
898 | int rc = 0; | 906 | int rc = X86EMUL_CONTINUE; |
899 | 907 | ||
900 | switch (c->ad_bytes) { | 908 | switch (c->ad_bytes) { |
901 | case 2: | 909 | case 2: |
@@ -916,14 +924,18 @@ int | |||
916 | x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 924 | x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) |
917 | { | 925 | { |
918 | struct decode_cache *c = &ctxt->decode; | 926 | struct decode_cache *c = &ctxt->decode; |
919 | int rc = 0; | 927 | int rc = X86EMUL_CONTINUE; |
920 | int mode = ctxt->mode; | 928 | int mode = ctxt->mode; |
921 | int def_op_bytes, def_ad_bytes, group; | 929 | int def_op_bytes, def_ad_bytes, group; |
922 | 930 | ||
923 | /* Shadow copy of register state. Committed on successful emulation. */ | ||
924 | 931 | ||
932 | /* we cannot decode insn before we complete previous rep insn */ | ||
933 | WARN_ON(ctxt->restart); | ||
934 | |||
935 | /* Shadow copy of register state. Committed on successful emulation. */ | ||
925 | memset(c, 0, sizeof(struct decode_cache)); | 936 | memset(c, 0, sizeof(struct decode_cache)); |
926 | c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu); | 937 | c->eip = ctxt->eip; |
938 | c->fetch.start = c->fetch.end = c->eip; | ||
927 | ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); | 939 | ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS); |
928 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | 940 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); |
929 | 941 | ||
@@ -1015,11 +1027,6 @@ done_prefixes: | |||
1015 | } | 1027 | } |
1016 | } | 1028 | } |
1017 | 1029 | ||
1018 | if (mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { | ||
1019 | kvm_report_emulation_failure(ctxt->vcpu, "invalid x86/64 instruction"); | ||
1020 | return -1; | ||
1021 | } | ||
1022 | |||
1023 | if (c->d & Group) { | 1030 | if (c->d & Group) { |
1024 | group = c->d & GroupMask; | 1031 | group = c->d & GroupMask; |
1025 | c->modrm = insn_fetch(u8, 1, c->eip); | 1032 | c->modrm = insn_fetch(u8, 1, c->eip); |
@@ -1046,7 +1053,7 @@ done_prefixes: | |||
1046 | rc = decode_modrm(ctxt, ops); | 1053 | rc = decode_modrm(ctxt, ops); |
1047 | else if (c->d & MemAbs) | 1054 | else if (c->d & MemAbs) |
1048 | rc = decode_abs(ctxt, ops); | 1055 | rc = decode_abs(ctxt, ops); |
1049 | if (rc) | 1056 | if (rc != X86EMUL_CONTINUE) |
1050 | goto done; | 1057 | goto done; |
1051 | 1058 | ||
1052 | if (!c->has_seg_override) | 1059 | if (!c->has_seg_override) |
@@ -1057,6 +1064,10 @@ done_prefixes: | |||
1057 | 1064 | ||
1058 | if (c->ad_bytes != 8) | 1065 | if (c->ad_bytes != 8) |
1059 | c->modrm_ea = (u32)c->modrm_ea; | 1066 | c->modrm_ea = (u32)c->modrm_ea; |
1067 | |||
1068 | if (c->rip_relative) | ||
1069 | c->modrm_ea += c->eip; | ||
1070 | |||
1060 | /* | 1071 | /* |
1061 | * Decode and fetch the source operand: register, memory | 1072 | * Decode and fetch the source operand: register, memory |
1062 | * or immediate. | 1073 | * or immediate. |
@@ -1091,6 +1102,8 @@ done_prefixes: | |||
1091 | break; | 1102 | break; |
1092 | } | 1103 | } |
1093 | c->src.type = OP_MEM; | 1104 | c->src.type = OP_MEM; |
1105 | c->src.ptr = (unsigned long *)c->modrm_ea; | ||
1106 | c->src.val = 0; | ||
1094 | break; | 1107 | break; |
1095 | case SrcImm: | 1108 | case SrcImm: |
1096 | case SrcImmU: | 1109 | case SrcImmU: |
@@ -1139,6 +1152,14 @@ done_prefixes: | |||
1139 | c->src.bytes = 1; | 1152 | c->src.bytes = 1; |
1140 | c->src.val = 1; | 1153 | c->src.val = 1; |
1141 | break; | 1154 | break; |
1155 | case SrcSI: | ||
1156 | c->src.type = OP_MEM; | ||
1157 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
1158 | c->src.ptr = (unsigned long *) | ||
1159 | register_address(c, seg_override_base(ctxt, c), | ||
1160 | c->regs[VCPU_REGS_RSI]); | ||
1161 | c->src.val = 0; | ||
1162 | break; | ||
1142 | } | 1163 | } |
1143 | 1164 | ||
1144 | /* | 1165 | /* |
@@ -1168,6 +1189,12 @@ done_prefixes: | |||
1168 | c->src2.bytes = 1; | 1189 | c->src2.bytes = 1; |
1169 | c->src2.val = 1; | 1190 | c->src2.val = 1; |
1170 | break; | 1191 | break; |
1192 | case Src2Mem16: | ||
1193 | c->src2.type = OP_MEM; | ||
1194 | c->src2.bytes = 2; | ||
1195 | c->src2.ptr = (unsigned long *)(c->modrm_ea + c->src.bytes); | ||
1196 | c->src2.val = 0; | ||
1197 | break; | ||
1171 | } | 1198 | } |
1172 | 1199 | ||
1173 | /* Decode and fetch the destination operand: register or memory. */ | 1200 | /* Decode and fetch the destination operand: register or memory. */ |
@@ -1180,6 +1207,7 @@ done_prefixes: | |||
1180 | c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); | 1207 | c->twobyte && (c->b == 0xb6 || c->b == 0xb7)); |
1181 | break; | 1208 | break; |
1182 | case DstMem: | 1209 | case DstMem: |
1210 | case DstMem64: | ||
1183 | if ((c->d & ModRM) && c->modrm_mod == 3) { | 1211 | if ((c->d & ModRM) && c->modrm_mod == 3) { |
1184 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 1212 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1185 | c->dst.type = OP_REG; | 1213 | c->dst.type = OP_REG; |
@@ -1188,12 +1216,24 @@ done_prefixes: | |||
1188 | break; | 1216 | break; |
1189 | } | 1217 | } |
1190 | c->dst.type = OP_MEM; | 1218 | c->dst.type = OP_MEM; |
1219 | c->dst.ptr = (unsigned long *)c->modrm_ea; | ||
1220 | if ((c->d & DstMask) == DstMem64) | ||
1221 | c->dst.bytes = 8; | ||
1222 | else | ||
1223 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
1224 | c->dst.val = 0; | ||
1225 | if (c->d & BitOp) { | ||
1226 | unsigned long mask = ~(c->dst.bytes * 8 - 1); | ||
1227 | |||
1228 | c->dst.ptr = (void *)c->dst.ptr + | ||
1229 | (c->src.val & mask) / 8; | ||
1230 | } | ||
1191 | break; | 1231 | break; |
1192 | case DstAcc: | 1232 | case DstAcc: |
1193 | c->dst.type = OP_REG; | 1233 | c->dst.type = OP_REG; |
1194 | c->dst.bytes = c->op_bytes; | 1234 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1195 | c->dst.ptr = &c->regs[VCPU_REGS_RAX]; | 1235 | c->dst.ptr = &c->regs[VCPU_REGS_RAX]; |
1196 | switch (c->op_bytes) { | 1236 | switch (c->dst.bytes) { |
1197 | case 1: | 1237 | case 1: |
1198 | c->dst.val = *(u8 *)c->dst.ptr; | 1238 | c->dst.val = *(u8 *)c->dst.ptr; |
1199 | break; | 1239 | break; |
@@ -1203,18 +1243,248 @@ done_prefixes: | |||
1203 | case 4: | 1243 | case 4: |
1204 | c->dst.val = *(u32 *)c->dst.ptr; | 1244 | c->dst.val = *(u32 *)c->dst.ptr; |
1205 | break; | 1245 | break; |
1246 | case 8: | ||
1247 | c->dst.val = *(u64 *)c->dst.ptr; | ||
1248 | break; | ||
1206 | } | 1249 | } |
1207 | c->dst.orig_val = c->dst.val; | 1250 | c->dst.orig_val = c->dst.val; |
1208 | break; | 1251 | break; |
1252 | case DstDI: | ||
1253 | c->dst.type = OP_MEM; | ||
1254 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
1255 | c->dst.ptr = (unsigned long *) | ||
1256 | register_address(c, es_base(ctxt), | ||
1257 | c->regs[VCPU_REGS_RDI]); | ||
1258 | c->dst.val = 0; | ||
1259 | break; | ||
1209 | } | 1260 | } |
1210 | 1261 | ||
1211 | if (c->rip_relative) | ||
1212 | c->modrm_ea += c->eip; | ||
1213 | |||
1214 | done: | 1262 | done: |
1215 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | 1263 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; |
1216 | } | 1264 | } |
1217 | 1265 | ||
1266 | static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, | ||
1267 | struct x86_emulate_ops *ops, | ||
1268 | unsigned int size, unsigned short port, | ||
1269 | void *dest) | ||
1270 | { | ||
1271 | struct read_cache *rc = &ctxt->decode.io_read; | ||
1272 | |||
1273 | if (rc->pos == rc->end) { /* refill pio read ahead */ | ||
1274 | struct decode_cache *c = &ctxt->decode; | ||
1275 | unsigned int in_page, n; | ||
1276 | unsigned int count = c->rep_prefix ? | ||
1277 | address_mask(c, c->regs[VCPU_REGS_RCX]) : 1; | ||
1278 | in_page = (ctxt->eflags & EFLG_DF) ? | ||
1279 | offset_in_page(c->regs[VCPU_REGS_RDI]) : | ||
1280 | PAGE_SIZE - offset_in_page(c->regs[VCPU_REGS_RDI]); | ||
1281 | n = min(min(in_page, (unsigned int)sizeof(rc->data)) / size, | ||
1282 | count); | ||
1283 | if (n == 0) | ||
1284 | n = 1; | ||
1285 | rc->pos = rc->end = 0; | ||
1286 | if (!ops->pio_in_emulated(size, port, rc->data, n, ctxt->vcpu)) | ||
1287 | return 0; | ||
1288 | rc->end = n * size; | ||
1289 | } | ||
1290 | |||
1291 | memcpy(dest, rc->data + rc->pos, size); | ||
1292 | rc->pos += size; | ||
1293 | return 1; | ||
1294 | } | ||
1295 | |||
1296 | static u32 desc_limit_scaled(struct desc_struct *desc) | ||
1297 | { | ||
1298 | u32 limit = get_desc_limit(desc); | ||
1299 | |||
1300 | return desc->g ? (limit << 12) | 0xfff : limit; | ||
1301 | } | ||
1302 | |||
1303 | static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, | ||
1304 | struct x86_emulate_ops *ops, | ||
1305 | u16 selector, struct desc_ptr *dt) | ||
1306 | { | ||
1307 | if (selector & 1 << 2) { | ||
1308 | struct desc_struct desc; | ||
1309 | memset (dt, 0, sizeof *dt); | ||
1310 | if (!ops->get_cached_descriptor(&desc, VCPU_SREG_LDTR, ctxt->vcpu)) | ||
1311 | return; | ||
1312 | |||
1313 | dt->size = desc_limit_scaled(&desc); /* what if limit > 65535? */ | ||
1314 | dt->address = get_desc_base(&desc); | ||
1315 | } else | ||
1316 | ops->get_gdt(dt, ctxt->vcpu); | ||
1317 | } | ||
1318 | |||
1319 | /* allowed just for 8 bytes segments */ | ||
1320 | static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, | ||
1321 | struct x86_emulate_ops *ops, | ||
1322 | u16 selector, struct desc_struct *desc) | ||
1323 | { | ||
1324 | struct desc_ptr dt; | ||
1325 | u16 index = selector >> 3; | ||
1326 | int ret; | ||
1327 | u32 err; | ||
1328 | ulong addr; | ||
1329 | |||
1330 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); | ||
1331 | |||
1332 | if (dt.size < index * 8 + 7) { | ||
1333 | kvm_inject_gp(ctxt->vcpu, selector & 0xfffc); | ||
1334 | return X86EMUL_PROPAGATE_FAULT; | ||
1335 | } | ||
1336 | addr = dt.address + index * 8; | ||
1337 | ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); | ||
1338 | if (ret == X86EMUL_PROPAGATE_FAULT) | ||
1339 | kvm_inject_page_fault(ctxt->vcpu, addr, err); | ||
1340 | |||
1341 | return ret; | ||
1342 | } | ||
1343 | |||
1344 | /* allowed just for 8 bytes segments */ | ||
1345 | static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, | ||
1346 | struct x86_emulate_ops *ops, | ||
1347 | u16 selector, struct desc_struct *desc) | ||
1348 | { | ||
1349 | struct desc_ptr dt; | ||
1350 | u16 index = selector >> 3; | ||
1351 | u32 err; | ||
1352 | ulong addr; | ||
1353 | int ret; | ||
1354 | |||
1355 | get_descriptor_table_ptr(ctxt, ops, selector, &dt); | ||
1356 | |||
1357 | if (dt.size < index * 8 + 7) { | ||
1358 | kvm_inject_gp(ctxt->vcpu, selector & 0xfffc); | ||
1359 | return X86EMUL_PROPAGATE_FAULT; | ||
1360 | } | ||
1361 | |||
1362 | addr = dt.address + index * 8; | ||
1363 | ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu, &err); | ||
1364 | if (ret == X86EMUL_PROPAGATE_FAULT) | ||
1365 | kvm_inject_page_fault(ctxt->vcpu, addr, err); | ||
1366 | |||
1367 | return ret; | ||
1368 | } | ||
1369 | |||
1370 | static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | ||
1371 | struct x86_emulate_ops *ops, | ||
1372 | u16 selector, int seg) | ||
1373 | { | ||
1374 | struct desc_struct seg_desc; | ||
1375 | u8 dpl, rpl, cpl; | ||
1376 | unsigned err_vec = GP_VECTOR; | ||
1377 | u32 err_code = 0; | ||
1378 | bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ | ||
1379 | int ret; | ||
1380 | |||
1381 | memset(&seg_desc, 0, sizeof seg_desc); | ||
1382 | |||
1383 | if ((seg <= VCPU_SREG_GS && ctxt->mode == X86EMUL_MODE_VM86) | ||
1384 | || ctxt->mode == X86EMUL_MODE_REAL) { | ||
1385 | /* set real mode segment descriptor */ | ||
1386 | set_desc_base(&seg_desc, selector << 4); | ||
1387 | set_desc_limit(&seg_desc, 0xffff); | ||
1388 | seg_desc.type = 3; | ||
1389 | seg_desc.p = 1; | ||
1390 | seg_desc.s = 1; | ||
1391 | goto load; | ||
1392 | } | ||
1393 | |||
1394 | /* NULL selector is not valid for TR, CS and SS */ | ||
1395 | if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) | ||
1396 | && null_selector) | ||
1397 | goto exception; | ||
1398 | |||
1399 | /* TR should be in GDT only */ | ||
1400 | if (seg == VCPU_SREG_TR && (selector & (1 << 2))) | ||
1401 | goto exception; | ||
1402 | |||
1403 | if (null_selector) /* for NULL selector skip all following checks */ | ||
1404 | goto load; | ||
1405 | |||
1406 | ret = read_segment_descriptor(ctxt, ops, selector, &seg_desc); | ||
1407 | if (ret != X86EMUL_CONTINUE) | ||
1408 | return ret; | ||
1409 | |||
1410 | err_code = selector & 0xfffc; | ||
1411 | err_vec = GP_VECTOR; | ||
1412 | |||
1413 | /* can't load system descriptor into segment selecor */ | ||
1414 | if (seg <= VCPU_SREG_GS && !seg_desc.s) | ||
1415 | goto exception; | ||
1416 | |||
1417 | if (!seg_desc.p) { | ||
1418 | err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR; | ||
1419 | goto exception; | ||
1420 | } | ||
1421 | |||
1422 | rpl = selector & 3; | ||
1423 | dpl = seg_desc.dpl; | ||
1424 | cpl = ops->cpl(ctxt->vcpu); | ||
1425 | |||
1426 | switch (seg) { | ||
1427 | case VCPU_SREG_SS: | ||
1428 | /* | ||
1429 | * segment is not a writable data segment or segment | ||
1430 | * selector's RPL != CPL or segment selector's RPL != CPL | ||
1431 | */ | ||
1432 | if (rpl != cpl || (seg_desc.type & 0xa) != 0x2 || dpl != cpl) | ||
1433 | goto exception; | ||
1434 | break; | ||
1435 | case VCPU_SREG_CS: | ||
1436 | if (!(seg_desc.type & 8)) | ||
1437 | goto exception; | ||
1438 | |||
1439 | if (seg_desc.type & 4) { | ||
1440 | /* conforming */ | ||
1441 | if (dpl > cpl) | ||
1442 | goto exception; | ||
1443 | } else { | ||
1444 | /* nonconforming */ | ||
1445 | if (rpl > cpl || dpl != cpl) | ||
1446 | goto exception; | ||
1447 | } | ||
1448 | /* CS(RPL) <- CPL */ | ||
1449 | selector = (selector & 0xfffc) | cpl; | ||
1450 | break; | ||
1451 | case VCPU_SREG_TR: | ||
1452 | if (seg_desc.s || (seg_desc.type != 1 && seg_desc.type != 9)) | ||
1453 | goto exception; | ||
1454 | break; | ||
1455 | case VCPU_SREG_LDTR: | ||
1456 | if (seg_desc.s || seg_desc.type != 2) | ||
1457 | goto exception; | ||
1458 | break; | ||
1459 | default: /* DS, ES, FS, or GS */ | ||
1460 | /* | ||
1461 | * segment is not a data or readable code segment or | ||
1462 | * ((segment is a data or nonconforming code segment) | ||
1463 | * and (both RPL and CPL > DPL)) | ||
1464 | */ | ||
1465 | if ((seg_desc.type & 0xa) == 0x8 || | ||
1466 | (((seg_desc.type & 0xc) != 0xc) && | ||
1467 | (rpl > dpl && cpl > dpl))) | ||
1468 | goto exception; | ||
1469 | break; | ||
1470 | } | ||
1471 | |||
1472 | if (seg_desc.s) { | ||
1473 | /* mark segment as accessed */ | ||
1474 | seg_desc.type |= 1; | ||
1475 | ret = write_segment_descriptor(ctxt, ops, selector, &seg_desc); | ||
1476 | if (ret != X86EMUL_CONTINUE) | ||
1477 | return ret; | ||
1478 | } | ||
1479 | load: | ||
1480 | ops->set_segment_selector(selector, seg, ctxt->vcpu); | ||
1481 | ops->set_cached_descriptor(&seg_desc, seg, ctxt->vcpu); | ||
1482 | return X86EMUL_CONTINUE; | ||
1483 | exception: | ||
1484 | kvm_queue_exception_e(ctxt->vcpu, err_vec, err_code); | ||
1485 | return X86EMUL_PROPAGATE_FAULT; | ||
1486 | } | ||
1487 | |||
1218 | static inline void emulate_push(struct x86_emulate_ctxt *ctxt) | 1488 | static inline void emulate_push(struct x86_emulate_ctxt *ctxt) |
1219 | { | 1489 | { |
1220 | struct decode_cache *c = &ctxt->decode; | 1490 | struct decode_cache *c = &ctxt->decode; |
@@ -1251,7 +1521,7 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, | |||
1251 | int rc; | 1521 | int rc; |
1252 | unsigned long val, change_mask; | 1522 | unsigned long val, change_mask; |
1253 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 1523 | int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; |
1254 | int cpl = kvm_x86_ops->get_cpl(ctxt->vcpu); | 1524 | int cpl = ops->cpl(ctxt->vcpu); |
1255 | 1525 | ||
1256 | rc = emulate_pop(ctxt, ops, &val, len); | 1526 | rc = emulate_pop(ctxt, ops, &val, len); |
1257 | if (rc != X86EMUL_CONTINUE) | 1527 | if (rc != X86EMUL_CONTINUE) |
@@ -1306,10 +1576,10 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, | |||
1306 | int rc; | 1576 | int rc; |
1307 | 1577 | ||
1308 | rc = emulate_pop(ctxt, ops, &selector, c->op_bytes); | 1578 | rc = emulate_pop(ctxt, ops, &selector, c->op_bytes); |
1309 | if (rc != 0) | 1579 | if (rc != X86EMUL_CONTINUE) |
1310 | return rc; | 1580 | return rc; |
1311 | 1581 | ||
1312 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, seg); | 1582 | rc = load_segment_descriptor(ctxt, ops, (u16)selector, seg); |
1313 | return rc; | 1583 | return rc; |
1314 | } | 1584 | } |
1315 | 1585 | ||
@@ -1332,7 +1602,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt, | |||
1332 | struct x86_emulate_ops *ops) | 1602 | struct x86_emulate_ops *ops) |
1333 | { | 1603 | { |
1334 | struct decode_cache *c = &ctxt->decode; | 1604 | struct decode_cache *c = &ctxt->decode; |
1335 | int rc = 0; | 1605 | int rc = X86EMUL_CONTINUE; |
1336 | int reg = VCPU_REGS_RDI; | 1606 | int reg = VCPU_REGS_RDI; |
1337 | 1607 | ||
1338 | while (reg >= VCPU_REGS_RAX) { | 1608 | while (reg >= VCPU_REGS_RAX) { |
@@ -1343,7 +1613,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt, | |||
1343 | } | 1613 | } |
1344 | 1614 | ||
1345 | rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes); | 1615 | rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes); |
1346 | if (rc != 0) | 1616 | if (rc != X86EMUL_CONTINUE) |
1347 | break; | 1617 | break; |
1348 | --reg; | 1618 | --reg; |
1349 | } | 1619 | } |
@@ -1354,12 +1624,8 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | |||
1354 | struct x86_emulate_ops *ops) | 1624 | struct x86_emulate_ops *ops) |
1355 | { | 1625 | { |
1356 | struct decode_cache *c = &ctxt->decode; | 1626 | struct decode_cache *c = &ctxt->decode; |
1357 | int rc; | ||
1358 | 1627 | ||
1359 | rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes); | 1628 | return emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes); |
1360 | if (rc != 0) | ||
1361 | return rc; | ||
1362 | return 0; | ||
1363 | } | 1629 | } |
1364 | 1630 | ||
1365 | static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt) | 1631 | static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt) |
@@ -1395,7 +1661,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1395 | struct x86_emulate_ops *ops) | 1661 | struct x86_emulate_ops *ops) |
1396 | { | 1662 | { |
1397 | struct decode_cache *c = &ctxt->decode; | 1663 | struct decode_cache *c = &ctxt->decode; |
1398 | int rc = 0; | ||
1399 | 1664 | ||
1400 | switch (c->modrm_reg) { | 1665 | switch (c->modrm_reg) { |
1401 | case 0 ... 1: /* test */ | 1666 | case 0 ... 1: /* test */ |
@@ -1408,11 +1673,9 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
1408 | emulate_1op("neg", c->dst, ctxt->eflags); | 1673 | emulate_1op("neg", c->dst, ctxt->eflags); |
1409 | break; | 1674 | break; |
1410 | default: | 1675 | default: |
1411 | DPRINTF("Cannot emulate %02x\n", c->b); | 1676 | return 0; |
1412 | rc = X86EMUL_UNHANDLEABLE; | ||
1413 | break; | ||
1414 | } | 1677 | } |
1415 | return rc; | 1678 | return 1; |
1416 | } | 1679 | } |
1417 | 1680 | ||
1418 | static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | 1681 | static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, |
@@ -1442,20 +1705,14 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | |||
1442 | emulate_push(ctxt); | 1705 | emulate_push(ctxt); |
1443 | break; | 1706 | break; |
1444 | } | 1707 | } |
1445 | return 0; | 1708 | return X86EMUL_CONTINUE; |
1446 | } | 1709 | } |
1447 | 1710 | ||
1448 | static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | 1711 | static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, |
1449 | struct x86_emulate_ops *ops, | 1712 | struct x86_emulate_ops *ops) |
1450 | unsigned long memop) | ||
1451 | { | 1713 | { |
1452 | struct decode_cache *c = &ctxt->decode; | 1714 | struct decode_cache *c = &ctxt->decode; |
1453 | u64 old, new; | 1715 | u64 old = c->dst.orig_val; |
1454 | int rc; | ||
1455 | |||
1456 | rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu); | ||
1457 | if (rc != X86EMUL_CONTINUE) | ||
1458 | return rc; | ||
1459 | 1716 | ||
1460 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || | 1717 | if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) || |
1461 | ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { | 1718 | ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) { |
@@ -1463,17 +1720,13 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1463 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); | 1720 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); |
1464 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); | 1721 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); |
1465 | ctxt->eflags &= ~EFLG_ZF; | 1722 | ctxt->eflags &= ~EFLG_ZF; |
1466 | |||
1467 | } else { | 1723 | } else { |
1468 | new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | | 1724 | c->dst.val = ((u64)c->regs[VCPU_REGS_RCX] << 32) | |
1469 | (u32) c->regs[VCPU_REGS_RBX]; | 1725 | (u32) c->regs[VCPU_REGS_RBX]; |
1470 | 1726 | ||
1471 | rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); | ||
1472 | if (rc != X86EMUL_CONTINUE) | ||
1473 | return rc; | ||
1474 | ctxt->eflags |= EFLG_ZF; | 1727 | ctxt->eflags |= EFLG_ZF; |
1475 | } | 1728 | } |
1476 | return 0; | 1729 | return X86EMUL_CONTINUE; |
1477 | } | 1730 | } |
1478 | 1731 | ||
1479 | static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, | 1732 | static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, |
@@ -1484,14 +1737,14 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt, | |||
1484 | unsigned long cs; | 1737 | unsigned long cs; |
1485 | 1738 | ||
1486 | rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes); | 1739 | rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes); |
1487 | if (rc) | 1740 | if (rc != X86EMUL_CONTINUE) |
1488 | return rc; | 1741 | return rc; |
1489 | if (c->op_bytes == 4) | 1742 | if (c->op_bytes == 4) |
1490 | c->eip = (u32)c->eip; | 1743 | c->eip = (u32)c->eip; |
1491 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); | 1744 | rc = emulate_pop(ctxt, ops, &cs, c->op_bytes); |
1492 | if (rc) | 1745 | if (rc != X86EMUL_CONTINUE) |
1493 | return rc; | 1746 | return rc; |
1494 | rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, VCPU_SREG_CS); | 1747 | rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS); |
1495 | return rc; | 1748 | return rc; |
1496 | } | 1749 | } |
1497 | 1750 | ||
@@ -1544,7 +1797,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1544 | default: | 1797 | default: |
1545 | break; | 1798 | break; |
1546 | } | 1799 | } |
1547 | return 0; | 1800 | return X86EMUL_CONTINUE; |
1548 | } | 1801 | } |
1549 | 1802 | ||
1550 | static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) | 1803 | static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) |
@@ -1598,8 +1851,11 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt) | |||
1598 | u64 msr_data; | 1851 | u64 msr_data; |
1599 | 1852 | ||
1600 | /* syscall is not available in real mode */ | 1853 | /* syscall is not available in real mode */ |
1601 | if (ctxt->mode == X86EMUL_MODE_REAL || ctxt->mode == X86EMUL_MODE_VM86) | 1854 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1602 | return X86EMUL_UNHANDLEABLE; | 1855 | ctxt->mode == X86EMUL_MODE_VM86) { |
1856 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
1857 | return X86EMUL_PROPAGATE_FAULT; | ||
1858 | } | ||
1603 | 1859 | ||
1604 | setup_syscalls_segments(ctxt, &cs, &ss); | 1860 | setup_syscalls_segments(ctxt, &cs, &ss); |
1605 | 1861 | ||
@@ -1649,14 +1905,16 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt) | |||
1649 | /* inject #GP if in real mode */ | 1905 | /* inject #GP if in real mode */ |
1650 | if (ctxt->mode == X86EMUL_MODE_REAL) { | 1906 | if (ctxt->mode == X86EMUL_MODE_REAL) { |
1651 | kvm_inject_gp(ctxt->vcpu, 0); | 1907 | kvm_inject_gp(ctxt->vcpu, 0); |
1652 | return X86EMUL_UNHANDLEABLE; | 1908 | return X86EMUL_PROPAGATE_FAULT; |
1653 | } | 1909 | } |
1654 | 1910 | ||
1655 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | 1911 | /* XXX sysenter/sysexit have not been tested in 64bit mode. |
1656 | * Therefore, we inject an #UD. | 1912 | * Therefore, we inject an #UD. |
1657 | */ | 1913 | */ |
1658 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 1914 | if (ctxt->mode == X86EMUL_MODE_PROT64) { |
1659 | return X86EMUL_UNHANDLEABLE; | 1915 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
1916 | return X86EMUL_PROPAGATE_FAULT; | ||
1917 | } | ||
1660 | 1918 | ||
1661 | setup_syscalls_segments(ctxt, &cs, &ss); | 1919 | setup_syscalls_segments(ctxt, &cs, &ss); |
1662 | 1920 | ||
@@ -1711,7 +1969,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1711 | if (ctxt->mode == X86EMUL_MODE_REAL || | 1969 | if (ctxt->mode == X86EMUL_MODE_REAL || |
1712 | ctxt->mode == X86EMUL_MODE_VM86) { | 1970 | ctxt->mode == X86EMUL_MODE_VM86) { |
1713 | kvm_inject_gp(ctxt->vcpu, 0); | 1971 | kvm_inject_gp(ctxt->vcpu, 0); |
1714 | return X86EMUL_UNHANDLEABLE; | 1972 | return X86EMUL_PROPAGATE_FAULT; |
1715 | } | 1973 | } |
1716 | 1974 | ||
1717 | setup_syscalls_segments(ctxt, &cs, &ss); | 1975 | setup_syscalls_segments(ctxt, &cs, &ss); |
@@ -1756,7 +2014,8 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt) | |||
1756 | return X86EMUL_CONTINUE; | 2014 | return X86EMUL_CONTINUE; |
1757 | } | 2015 | } |
1758 | 2016 | ||
1759 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | 2017 | static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt, |
2018 | struct x86_emulate_ops *ops) | ||
1760 | { | 2019 | { |
1761 | int iopl; | 2020 | int iopl; |
1762 | if (ctxt->mode == X86EMUL_MODE_REAL) | 2021 | if (ctxt->mode == X86EMUL_MODE_REAL) |
@@ -1764,7 +2023,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) | |||
1764 | if (ctxt->mode == X86EMUL_MODE_VM86) | 2023 | if (ctxt->mode == X86EMUL_MODE_VM86) |
1765 | return true; | 2024 | return true; |
1766 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 2025 | iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; |
1767 | return kvm_x86_ops->get_cpl(ctxt->vcpu) > iopl; | 2026 | return ops->cpl(ctxt->vcpu) > iopl; |
1768 | } | 2027 | } |
1769 | 2028 | ||
1770 | static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, | 2029 | static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, |
@@ -1801,22 +2060,419 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt, | |||
1801 | struct x86_emulate_ops *ops, | 2060 | struct x86_emulate_ops *ops, |
1802 | u16 port, u16 len) | 2061 | u16 port, u16 len) |
1803 | { | 2062 | { |
1804 | if (emulator_bad_iopl(ctxt)) | 2063 | if (emulator_bad_iopl(ctxt, ops)) |
1805 | if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) | 2064 | if (!emulator_io_port_access_allowed(ctxt, ops, port, len)) |
1806 | return false; | 2065 | return false; |
1807 | return true; | 2066 | return true; |
1808 | } | 2067 | } |
1809 | 2068 | ||
2069 | static u32 get_cached_descriptor_base(struct x86_emulate_ctxt *ctxt, | ||
2070 | struct x86_emulate_ops *ops, | ||
2071 | int seg) | ||
2072 | { | ||
2073 | struct desc_struct desc; | ||
2074 | if (ops->get_cached_descriptor(&desc, seg, ctxt->vcpu)) | ||
2075 | return get_desc_base(&desc); | ||
2076 | else | ||
2077 | return ~0; | ||
2078 | } | ||
2079 | |||
2080 | static void save_state_to_tss16(struct x86_emulate_ctxt *ctxt, | ||
2081 | struct x86_emulate_ops *ops, | ||
2082 | struct tss_segment_16 *tss) | ||
2083 | { | ||
2084 | struct decode_cache *c = &ctxt->decode; | ||
2085 | |||
2086 | tss->ip = c->eip; | ||
2087 | tss->flag = ctxt->eflags; | ||
2088 | tss->ax = c->regs[VCPU_REGS_RAX]; | ||
2089 | tss->cx = c->regs[VCPU_REGS_RCX]; | ||
2090 | tss->dx = c->regs[VCPU_REGS_RDX]; | ||
2091 | tss->bx = c->regs[VCPU_REGS_RBX]; | ||
2092 | tss->sp = c->regs[VCPU_REGS_RSP]; | ||
2093 | tss->bp = c->regs[VCPU_REGS_RBP]; | ||
2094 | tss->si = c->regs[VCPU_REGS_RSI]; | ||
2095 | tss->di = c->regs[VCPU_REGS_RDI]; | ||
2096 | |||
2097 | tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu); | ||
2098 | tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); | ||
2099 | tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu); | ||
2100 | tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu); | ||
2101 | tss->ldt = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu); | ||
2102 | } | ||
2103 | |||
2104 | static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt, | ||
2105 | struct x86_emulate_ops *ops, | ||
2106 | struct tss_segment_16 *tss) | ||
2107 | { | ||
2108 | struct decode_cache *c = &ctxt->decode; | ||
2109 | int ret; | ||
2110 | |||
2111 | c->eip = tss->ip; | ||
2112 | ctxt->eflags = tss->flag | 2; | ||
2113 | c->regs[VCPU_REGS_RAX] = tss->ax; | ||
2114 | c->regs[VCPU_REGS_RCX] = tss->cx; | ||
2115 | c->regs[VCPU_REGS_RDX] = tss->dx; | ||
2116 | c->regs[VCPU_REGS_RBX] = tss->bx; | ||
2117 | c->regs[VCPU_REGS_RSP] = tss->sp; | ||
2118 | c->regs[VCPU_REGS_RBP] = tss->bp; | ||
2119 | c->regs[VCPU_REGS_RSI] = tss->si; | ||
2120 | c->regs[VCPU_REGS_RDI] = tss->di; | ||
2121 | |||
2122 | /* | ||
2123 | * SDM says that segment selectors are loaded before segment | ||
2124 | * descriptors | ||
2125 | */ | ||
2126 | ops->set_segment_selector(tss->ldt, VCPU_SREG_LDTR, ctxt->vcpu); | ||
2127 | ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu); | ||
2128 | ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu); | ||
2129 | ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu); | ||
2130 | ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu); | ||
2131 | |||
2132 | /* | ||
2133 | * Now load segment descriptors. If fault happenes at this stage | ||
2134 | * it is handled in a context of new task | ||
2135 | */ | ||
2136 | ret = load_segment_descriptor(ctxt, ops, tss->ldt, VCPU_SREG_LDTR); | ||
2137 | if (ret != X86EMUL_CONTINUE) | ||
2138 | return ret; | ||
2139 | ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES); | ||
2140 | if (ret != X86EMUL_CONTINUE) | ||
2141 | return ret; | ||
2142 | ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS); | ||
2143 | if (ret != X86EMUL_CONTINUE) | ||
2144 | return ret; | ||
2145 | ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS); | ||
2146 | if (ret != X86EMUL_CONTINUE) | ||
2147 | return ret; | ||
2148 | ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS); | ||
2149 | if (ret != X86EMUL_CONTINUE) | ||
2150 | return ret; | ||
2151 | |||
2152 | return X86EMUL_CONTINUE; | ||
2153 | } | ||
2154 | |||
2155 | static int task_switch_16(struct x86_emulate_ctxt *ctxt, | ||
2156 | struct x86_emulate_ops *ops, | ||
2157 | u16 tss_selector, u16 old_tss_sel, | ||
2158 | ulong old_tss_base, struct desc_struct *new_desc) | ||
2159 | { | ||
2160 | struct tss_segment_16 tss_seg; | ||
2161 | int ret; | ||
2162 | u32 err, new_tss_base = get_desc_base(new_desc); | ||
2163 | |||
2164 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2165 | &err); | ||
2166 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2167 | /* FIXME: need to provide precise fault address */ | ||
2168 | kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); | ||
2169 | return ret; | ||
2170 | } | ||
2171 | |||
2172 | save_state_to_tss16(ctxt, ops, &tss_seg); | ||
2173 | |||
2174 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2175 | &err); | ||
2176 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2177 | /* FIXME: need to provide precise fault address */ | ||
2178 | kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); | ||
2179 | return ret; | ||
2180 | } | ||
2181 | |||
2182 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2183 | &err); | ||
2184 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2185 | /* FIXME: need to provide precise fault address */ | ||
2186 | kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); | ||
2187 | return ret; | ||
2188 | } | ||
2189 | |||
2190 | if (old_tss_sel != 0xffff) { | ||
2191 | tss_seg.prev_task_link = old_tss_sel; | ||
2192 | |||
2193 | ret = ops->write_std(new_tss_base, | ||
2194 | &tss_seg.prev_task_link, | ||
2195 | sizeof tss_seg.prev_task_link, | ||
2196 | ctxt->vcpu, &err); | ||
2197 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2198 | /* FIXME: need to provide precise fault address */ | ||
2199 | kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); | ||
2200 | return ret; | ||
2201 | } | ||
2202 | } | ||
2203 | |||
2204 | return load_state_from_tss16(ctxt, ops, &tss_seg); | ||
2205 | } | ||
2206 | |||
2207 | static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt, | ||
2208 | struct x86_emulate_ops *ops, | ||
2209 | struct tss_segment_32 *tss) | ||
2210 | { | ||
2211 | struct decode_cache *c = &ctxt->decode; | ||
2212 | |||
2213 | tss->cr3 = ops->get_cr(3, ctxt->vcpu); | ||
2214 | tss->eip = c->eip; | ||
2215 | tss->eflags = ctxt->eflags; | ||
2216 | tss->eax = c->regs[VCPU_REGS_RAX]; | ||
2217 | tss->ecx = c->regs[VCPU_REGS_RCX]; | ||
2218 | tss->edx = c->regs[VCPU_REGS_RDX]; | ||
2219 | tss->ebx = c->regs[VCPU_REGS_RBX]; | ||
2220 | tss->esp = c->regs[VCPU_REGS_RSP]; | ||
2221 | tss->ebp = c->regs[VCPU_REGS_RBP]; | ||
2222 | tss->esi = c->regs[VCPU_REGS_RSI]; | ||
2223 | tss->edi = c->regs[VCPU_REGS_RDI]; | ||
2224 | |||
2225 | tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu); | ||
2226 | tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); | ||
2227 | tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu); | ||
2228 | tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu); | ||
2229 | tss->fs = ops->get_segment_selector(VCPU_SREG_FS, ctxt->vcpu); | ||
2230 | tss->gs = ops->get_segment_selector(VCPU_SREG_GS, ctxt->vcpu); | ||
2231 | tss->ldt_selector = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu); | ||
2232 | } | ||
2233 | |||
2234 | static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt, | ||
2235 | struct x86_emulate_ops *ops, | ||
2236 | struct tss_segment_32 *tss) | ||
2237 | { | ||
2238 | struct decode_cache *c = &ctxt->decode; | ||
2239 | int ret; | ||
2240 | |||
2241 | ops->set_cr(3, tss->cr3, ctxt->vcpu); | ||
2242 | c->eip = tss->eip; | ||
2243 | ctxt->eflags = tss->eflags | 2; | ||
2244 | c->regs[VCPU_REGS_RAX] = tss->eax; | ||
2245 | c->regs[VCPU_REGS_RCX] = tss->ecx; | ||
2246 | c->regs[VCPU_REGS_RDX] = tss->edx; | ||
2247 | c->regs[VCPU_REGS_RBX] = tss->ebx; | ||
2248 | c->regs[VCPU_REGS_RSP] = tss->esp; | ||
2249 | c->regs[VCPU_REGS_RBP] = tss->ebp; | ||
2250 | c->regs[VCPU_REGS_RSI] = tss->esi; | ||
2251 | c->regs[VCPU_REGS_RDI] = tss->edi; | ||
2252 | |||
2253 | /* | ||
2254 | * SDM says that segment selectors are loaded before segment | ||
2255 | * descriptors | ||
2256 | */ | ||
2257 | ops->set_segment_selector(tss->ldt_selector, VCPU_SREG_LDTR, ctxt->vcpu); | ||
2258 | ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu); | ||
2259 | ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu); | ||
2260 | ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu); | ||
2261 | ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu); | ||
2262 | ops->set_segment_selector(tss->fs, VCPU_SREG_FS, ctxt->vcpu); | ||
2263 | ops->set_segment_selector(tss->gs, VCPU_SREG_GS, ctxt->vcpu); | ||
2264 | |||
2265 | /* | ||
2266 | * Now load segment descriptors. If fault happenes at this stage | ||
2267 | * it is handled in a context of new task | ||
2268 | */ | ||
2269 | ret = load_segment_descriptor(ctxt, ops, tss->ldt_selector, VCPU_SREG_LDTR); | ||
2270 | if (ret != X86EMUL_CONTINUE) | ||
2271 | return ret; | ||
2272 | ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES); | ||
2273 | if (ret != X86EMUL_CONTINUE) | ||
2274 | return ret; | ||
2275 | ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS); | ||
2276 | if (ret != X86EMUL_CONTINUE) | ||
2277 | return ret; | ||
2278 | ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS); | ||
2279 | if (ret != X86EMUL_CONTINUE) | ||
2280 | return ret; | ||
2281 | ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS); | ||
2282 | if (ret != X86EMUL_CONTINUE) | ||
2283 | return ret; | ||
2284 | ret = load_segment_descriptor(ctxt, ops, tss->fs, VCPU_SREG_FS); | ||
2285 | if (ret != X86EMUL_CONTINUE) | ||
2286 | return ret; | ||
2287 | ret = load_segment_descriptor(ctxt, ops, tss->gs, VCPU_SREG_GS); | ||
2288 | if (ret != X86EMUL_CONTINUE) | ||
2289 | return ret; | ||
2290 | |||
2291 | return X86EMUL_CONTINUE; | ||
2292 | } | ||
2293 | |||
2294 | static int task_switch_32(struct x86_emulate_ctxt *ctxt, | ||
2295 | struct x86_emulate_ops *ops, | ||
2296 | u16 tss_selector, u16 old_tss_sel, | ||
2297 | ulong old_tss_base, struct desc_struct *new_desc) | ||
2298 | { | ||
2299 | struct tss_segment_32 tss_seg; | ||
2300 | int ret; | ||
2301 | u32 err, new_tss_base = get_desc_base(new_desc); | ||
2302 | |||
2303 | ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2304 | &err); | ||
2305 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2306 | /* FIXME: need to provide precise fault address */ | ||
2307 | kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); | ||
2308 | return ret; | ||
2309 | } | ||
2310 | |||
2311 | save_state_to_tss32(ctxt, ops, &tss_seg); | ||
2312 | |||
2313 | ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2314 | &err); | ||
2315 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2316 | /* FIXME: need to provide precise fault address */ | ||
2317 | kvm_inject_page_fault(ctxt->vcpu, old_tss_base, err); | ||
2318 | return ret; | ||
2319 | } | ||
2320 | |||
2321 | ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu, | ||
2322 | &err); | ||
2323 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2324 | /* FIXME: need to provide precise fault address */ | ||
2325 | kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); | ||
2326 | return ret; | ||
2327 | } | ||
2328 | |||
2329 | if (old_tss_sel != 0xffff) { | ||
2330 | tss_seg.prev_task_link = old_tss_sel; | ||
2331 | |||
2332 | ret = ops->write_std(new_tss_base, | ||
2333 | &tss_seg.prev_task_link, | ||
2334 | sizeof tss_seg.prev_task_link, | ||
2335 | ctxt->vcpu, &err); | ||
2336 | if (ret == X86EMUL_PROPAGATE_FAULT) { | ||
2337 | /* FIXME: need to provide precise fault address */ | ||
2338 | kvm_inject_page_fault(ctxt->vcpu, new_tss_base, err); | ||
2339 | return ret; | ||
2340 | } | ||
2341 | } | ||
2342 | |||
2343 | return load_state_from_tss32(ctxt, ops, &tss_seg); | ||
2344 | } | ||
2345 | |||
2346 | static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, | ||
2347 | struct x86_emulate_ops *ops, | ||
2348 | u16 tss_selector, int reason, | ||
2349 | bool has_error_code, u32 error_code) | ||
2350 | { | ||
2351 | struct desc_struct curr_tss_desc, next_tss_desc; | ||
2352 | int ret; | ||
2353 | u16 old_tss_sel = ops->get_segment_selector(VCPU_SREG_TR, ctxt->vcpu); | ||
2354 | ulong old_tss_base = | ||
2355 | get_cached_descriptor_base(ctxt, ops, VCPU_SREG_TR); | ||
2356 | u32 desc_limit; | ||
2357 | |||
2358 | /* FIXME: old_tss_base == ~0 ? */ | ||
2359 | |||
2360 | ret = read_segment_descriptor(ctxt, ops, tss_selector, &next_tss_desc); | ||
2361 | if (ret != X86EMUL_CONTINUE) | ||
2362 | return ret; | ||
2363 | ret = read_segment_descriptor(ctxt, ops, old_tss_sel, &curr_tss_desc); | ||
2364 | if (ret != X86EMUL_CONTINUE) | ||
2365 | return ret; | ||
2366 | |||
2367 | /* FIXME: check that next_tss_desc is tss */ | ||
2368 | |||
2369 | if (reason != TASK_SWITCH_IRET) { | ||
2370 | if ((tss_selector & 3) > next_tss_desc.dpl || | ||
2371 | ops->cpl(ctxt->vcpu) > next_tss_desc.dpl) { | ||
2372 | kvm_inject_gp(ctxt->vcpu, 0); | ||
2373 | return X86EMUL_PROPAGATE_FAULT; | ||
2374 | } | ||
2375 | } | ||
2376 | |||
2377 | desc_limit = desc_limit_scaled(&next_tss_desc); | ||
2378 | if (!next_tss_desc.p || | ||
2379 | ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || | ||
2380 | desc_limit < 0x2b)) { | ||
2381 | kvm_queue_exception_e(ctxt->vcpu, TS_VECTOR, | ||
2382 | tss_selector & 0xfffc); | ||
2383 | return X86EMUL_PROPAGATE_FAULT; | ||
2384 | } | ||
2385 | |||
2386 | if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { | ||
2387 | curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */ | ||
2388 | write_segment_descriptor(ctxt, ops, old_tss_sel, | ||
2389 | &curr_tss_desc); | ||
2390 | } | ||
2391 | |||
2392 | if (reason == TASK_SWITCH_IRET) | ||
2393 | ctxt->eflags = ctxt->eflags & ~X86_EFLAGS_NT; | ||
2394 | |||
2395 | /* set back link to prev task only if NT bit is set in eflags | ||
2396 | note that old_tss_sel is not used afetr this point */ | ||
2397 | if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE) | ||
2398 | old_tss_sel = 0xffff; | ||
2399 | |||
2400 | if (next_tss_desc.type & 8) | ||
2401 | ret = task_switch_32(ctxt, ops, tss_selector, old_tss_sel, | ||
2402 | old_tss_base, &next_tss_desc); | ||
2403 | else | ||
2404 | ret = task_switch_16(ctxt, ops, tss_selector, old_tss_sel, | ||
2405 | old_tss_base, &next_tss_desc); | ||
2406 | if (ret != X86EMUL_CONTINUE) | ||
2407 | return ret; | ||
2408 | |||
2409 | if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) | ||
2410 | ctxt->eflags = ctxt->eflags | X86_EFLAGS_NT; | ||
2411 | |||
2412 | if (reason != TASK_SWITCH_IRET) { | ||
2413 | next_tss_desc.type |= (1 << 1); /* set busy flag */ | ||
2414 | write_segment_descriptor(ctxt, ops, tss_selector, | ||
2415 | &next_tss_desc); | ||
2416 | } | ||
2417 | |||
2418 | ops->set_cr(0, ops->get_cr(0, ctxt->vcpu) | X86_CR0_TS, ctxt->vcpu); | ||
2419 | ops->set_cached_descriptor(&next_tss_desc, VCPU_SREG_TR, ctxt->vcpu); | ||
2420 | ops->set_segment_selector(tss_selector, VCPU_SREG_TR, ctxt->vcpu); | ||
2421 | |||
2422 | if (has_error_code) { | ||
2423 | struct decode_cache *c = &ctxt->decode; | ||
2424 | |||
2425 | c->op_bytes = c->ad_bytes = (next_tss_desc.type & 8) ? 4 : 2; | ||
2426 | c->lock_prefix = 0; | ||
2427 | c->src.val = (unsigned long) error_code; | ||
2428 | emulate_push(ctxt); | ||
2429 | } | ||
2430 | |||
2431 | return ret; | ||
2432 | } | ||
2433 | |||
2434 | int emulator_task_switch(struct x86_emulate_ctxt *ctxt, | ||
2435 | struct x86_emulate_ops *ops, | ||
2436 | u16 tss_selector, int reason, | ||
2437 | bool has_error_code, u32 error_code) | ||
2438 | { | ||
2439 | struct decode_cache *c = &ctxt->decode; | ||
2440 | int rc; | ||
2441 | |||
2442 | memset(c, 0, sizeof(struct decode_cache)); | ||
2443 | c->eip = ctxt->eip; | ||
2444 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | ||
2445 | c->dst.type = OP_NONE; | ||
2446 | |||
2447 | rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason, | ||
2448 | has_error_code, error_code); | ||
2449 | |||
2450 | if (rc == X86EMUL_CONTINUE) { | ||
2451 | memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); | ||
2452 | kvm_rip_write(ctxt->vcpu, c->eip); | ||
2453 | rc = writeback(ctxt, ops); | ||
2454 | } | ||
2455 | |||
2456 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | ||
2457 | } | ||
2458 | |||
2459 | static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, | ||
2460 | int reg, struct operand *op) | ||
2461 | { | ||
2462 | struct decode_cache *c = &ctxt->decode; | ||
2463 | int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; | ||
2464 | |||
2465 | register_address_increment(c, &c->regs[reg], df * op->bytes); | ||
2466 | op->ptr = (unsigned long *)register_address(c, base, c->regs[reg]); | ||
2467 | } | ||
2468 | |||
1810 | int | 2469 | int |
1811 | x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 2470 | x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) |
1812 | { | 2471 | { |
1813 | unsigned long memop = 0; | ||
1814 | u64 msr_data; | 2472 | u64 msr_data; |
1815 | unsigned long saved_eip = 0; | ||
1816 | struct decode_cache *c = &ctxt->decode; | 2473 | struct decode_cache *c = &ctxt->decode; |
1817 | unsigned int port; | 2474 | int rc = X86EMUL_CONTINUE; |
1818 | int io_dir_in; | 2475 | int saved_dst_type = c->dst.type; |
1819 | int rc = 0; | ||
1820 | 2476 | ||
1821 | ctxt->interruptibility = 0; | 2477 | ctxt->interruptibility = 0; |
1822 | 2478 | ||
@@ -1826,26 +2482,30 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1826 | */ | 2482 | */ |
1827 | 2483 | ||
1828 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); | 2484 | memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs); |
1829 | saved_eip = c->eip; | 2485 | |
2486 | if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) { | ||
2487 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
2488 | goto done; | ||
2489 | } | ||
1830 | 2490 | ||
1831 | /* LOCK prefix is allowed only with some instructions */ | 2491 | /* LOCK prefix is allowed only with some instructions */ |
1832 | if (c->lock_prefix && !(c->d & Lock)) { | 2492 | if (c->lock_prefix && (!(c->d & Lock) || c->dst.type != OP_MEM)) { |
1833 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | 2493 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
1834 | goto done; | 2494 | goto done; |
1835 | } | 2495 | } |
1836 | 2496 | ||
1837 | /* Privileged instruction can be executed only in CPL=0 */ | 2497 | /* Privileged instruction can be executed only in CPL=0 */ |
1838 | if ((c->d & Priv) && kvm_x86_ops->get_cpl(ctxt->vcpu)) { | 2498 | if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) { |
1839 | kvm_inject_gp(ctxt->vcpu, 0); | 2499 | kvm_inject_gp(ctxt->vcpu, 0); |
1840 | goto done; | 2500 | goto done; |
1841 | } | 2501 | } |
1842 | 2502 | ||
1843 | if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs)) | ||
1844 | memop = c->modrm_ea; | ||
1845 | |||
1846 | if (c->rep_prefix && (c->d & String)) { | 2503 | if (c->rep_prefix && (c->d & String)) { |
2504 | ctxt->restart = true; | ||
1847 | /* All REP prefixes have the same first termination condition */ | 2505 | /* All REP prefixes have the same first termination condition */ |
1848 | if (c->regs[VCPU_REGS_RCX] == 0) { | 2506 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { |
2507 | string_done: | ||
2508 | ctxt->restart = false; | ||
1849 | kvm_rip_write(ctxt->vcpu, c->eip); | 2509 | kvm_rip_write(ctxt->vcpu, c->eip); |
1850 | goto done; | 2510 | goto done; |
1851 | } | 2511 | } |
@@ -1857,25 +2517,18 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1857 | * - if REPNE/REPNZ and ZF = 1 then done | 2517 | * - if REPNE/REPNZ and ZF = 1 then done |
1858 | */ | 2518 | */ |
1859 | if ((c->b == 0xa6) || (c->b == 0xa7) || | 2519 | if ((c->b == 0xa6) || (c->b == 0xa7) || |
1860 | (c->b == 0xae) || (c->b == 0xaf)) { | 2520 | (c->b == 0xae) || (c->b == 0xaf)) { |
1861 | if ((c->rep_prefix == REPE_PREFIX) && | 2521 | if ((c->rep_prefix == REPE_PREFIX) && |
1862 | ((ctxt->eflags & EFLG_ZF) == 0)) { | 2522 | ((ctxt->eflags & EFLG_ZF) == 0)) |
1863 | kvm_rip_write(ctxt->vcpu, c->eip); | 2523 | goto string_done; |
1864 | goto done; | ||
1865 | } | ||
1866 | if ((c->rep_prefix == REPNE_PREFIX) && | 2524 | if ((c->rep_prefix == REPNE_PREFIX) && |
1867 | ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) { | 2525 | ((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) |
1868 | kvm_rip_write(ctxt->vcpu, c->eip); | 2526 | goto string_done; |
1869 | goto done; | ||
1870 | } | ||
1871 | } | 2527 | } |
1872 | c->regs[VCPU_REGS_RCX]--; | 2528 | c->eip = ctxt->eip; |
1873 | c->eip = kvm_rip_read(ctxt->vcpu); | ||
1874 | } | 2529 | } |
1875 | 2530 | ||
1876 | if (c->src.type == OP_MEM) { | 2531 | if (c->src.type == OP_MEM) { |
1877 | c->src.ptr = (unsigned long *)memop; | ||
1878 | c->src.val = 0; | ||
1879 | rc = ops->read_emulated((unsigned long)c->src.ptr, | 2532 | rc = ops->read_emulated((unsigned long)c->src.ptr, |
1880 | &c->src.val, | 2533 | &c->src.val, |
1881 | c->src.bytes, | 2534 | c->src.bytes, |
@@ -1885,29 +2538,25 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1885 | c->src.orig_val = c->src.val; | 2538 | c->src.orig_val = c->src.val; |
1886 | } | 2539 | } |
1887 | 2540 | ||
2541 | if (c->src2.type == OP_MEM) { | ||
2542 | rc = ops->read_emulated((unsigned long)c->src2.ptr, | ||
2543 | &c->src2.val, | ||
2544 | c->src2.bytes, | ||
2545 | ctxt->vcpu); | ||
2546 | if (rc != X86EMUL_CONTINUE) | ||
2547 | goto done; | ||
2548 | } | ||
2549 | |||
1888 | if ((c->d & DstMask) == ImplicitOps) | 2550 | if ((c->d & DstMask) == ImplicitOps) |
1889 | goto special_insn; | 2551 | goto special_insn; |
1890 | 2552 | ||
1891 | 2553 | ||
1892 | if (c->dst.type == OP_MEM) { | 2554 | if ((c->dst.type == OP_MEM) && !(c->d & Mov)) { |
1893 | c->dst.ptr = (unsigned long *)memop; | 2555 | /* optimisation - avoid slow emulated read if Mov */ |
1894 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 2556 | rc = ops->read_emulated((unsigned long)c->dst.ptr, &c->dst.val, |
1895 | c->dst.val = 0; | 2557 | c->dst.bytes, ctxt->vcpu); |
1896 | if (c->d & BitOp) { | 2558 | if (rc != X86EMUL_CONTINUE) |
1897 | unsigned long mask = ~(c->dst.bytes * 8 - 1); | 2559 | goto done; |
1898 | |||
1899 | c->dst.ptr = (void *)c->dst.ptr + | ||
1900 | (c->src.val & mask) / 8; | ||
1901 | } | ||
1902 | if (!(c->d & Mov)) { | ||
1903 | /* optimisation - avoid slow emulated read */ | ||
1904 | rc = ops->read_emulated((unsigned long)c->dst.ptr, | ||
1905 | &c->dst.val, | ||
1906 | c->dst.bytes, | ||
1907 | ctxt->vcpu); | ||
1908 | if (rc != X86EMUL_CONTINUE) | ||
1909 | goto done; | ||
1910 | } | ||
1911 | } | 2560 | } |
1912 | c->dst.orig_val = c->dst.val; | 2561 | c->dst.orig_val = c->dst.val; |
1913 | 2562 | ||
@@ -1926,7 +2575,7 @@ special_insn: | |||
1926 | break; | 2575 | break; |
1927 | case 0x07: /* pop es */ | 2576 | case 0x07: /* pop es */ |
1928 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES); | 2577 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES); |
1929 | if (rc != 0) | 2578 | if (rc != X86EMUL_CONTINUE) |
1930 | goto done; | 2579 | goto done; |
1931 | break; | 2580 | break; |
1932 | case 0x08 ... 0x0d: | 2581 | case 0x08 ... 0x0d: |
@@ -1945,7 +2594,7 @@ special_insn: | |||
1945 | break; | 2594 | break; |
1946 | case 0x17: /* pop ss */ | 2595 | case 0x17: /* pop ss */ |
1947 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS); | 2596 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS); |
1948 | if (rc != 0) | 2597 | if (rc != X86EMUL_CONTINUE) |
1949 | goto done; | 2598 | goto done; |
1950 | break; | 2599 | break; |
1951 | case 0x18 ... 0x1d: | 2600 | case 0x18 ... 0x1d: |
@@ -1957,7 +2606,7 @@ special_insn: | |||
1957 | break; | 2606 | break; |
1958 | case 0x1f: /* pop ds */ | 2607 | case 0x1f: /* pop ds */ |
1959 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS); | 2608 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS); |
1960 | if (rc != 0) | 2609 | if (rc != X86EMUL_CONTINUE) |
1961 | goto done; | 2610 | goto done; |
1962 | break; | 2611 | break; |
1963 | case 0x20 ... 0x25: | 2612 | case 0x20 ... 0x25: |
@@ -1988,7 +2637,7 @@ special_insn: | |||
1988 | case 0x58 ... 0x5f: /* pop reg */ | 2637 | case 0x58 ... 0x5f: /* pop reg */ |
1989 | pop_instruction: | 2638 | pop_instruction: |
1990 | rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes); | 2639 | rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes); |
1991 | if (rc != 0) | 2640 | if (rc != X86EMUL_CONTINUE) |
1992 | goto done; | 2641 | goto done; |
1993 | break; | 2642 | break; |
1994 | case 0x60: /* pusha */ | 2643 | case 0x60: /* pusha */ |
@@ -1996,7 +2645,7 @@ special_insn: | |||
1996 | break; | 2645 | break; |
1997 | case 0x61: /* popa */ | 2646 | case 0x61: /* popa */ |
1998 | rc = emulate_popa(ctxt, ops); | 2647 | rc = emulate_popa(ctxt, ops); |
1999 | if (rc != 0) | 2648 | if (rc != X86EMUL_CONTINUE) |
2000 | goto done; | 2649 | goto done; |
2001 | break; | 2650 | break; |
2002 | case 0x63: /* movsxd */ | 2651 | case 0x63: /* movsxd */ |
@@ -2010,47 +2659,29 @@ special_insn: | |||
2010 | break; | 2659 | break; |
2011 | case 0x6c: /* insb */ | 2660 | case 0x6c: /* insb */ |
2012 | case 0x6d: /* insw/insd */ | 2661 | case 0x6d: /* insw/insd */ |
2662 | c->dst.bytes = min(c->dst.bytes, 4u); | ||
2013 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], | 2663 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], |
2014 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | 2664 | c->dst.bytes)) { |
2015 | kvm_inject_gp(ctxt->vcpu, 0); | 2665 | kvm_inject_gp(ctxt->vcpu, 0); |
2016 | goto done; | 2666 | goto done; |
2017 | } | 2667 | } |
2018 | if (kvm_emulate_pio_string(ctxt->vcpu, | 2668 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, |
2019 | 1, | 2669 | c->regs[VCPU_REGS_RDX], &c->dst.val)) |
2020 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2670 | goto done; /* IO is needed, skip writeback */ |
2021 | c->rep_prefix ? | 2671 | break; |
2022 | address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, | ||
2023 | (ctxt->eflags & EFLG_DF), | ||
2024 | register_address(c, es_base(ctxt), | ||
2025 | c->regs[VCPU_REGS_RDI]), | ||
2026 | c->rep_prefix, | ||
2027 | c->regs[VCPU_REGS_RDX]) == 0) { | ||
2028 | c->eip = saved_eip; | ||
2029 | return -1; | ||
2030 | } | ||
2031 | return 0; | ||
2032 | case 0x6e: /* outsb */ | 2672 | case 0x6e: /* outsb */ |
2033 | case 0x6f: /* outsw/outsd */ | 2673 | case 0x6f: /* outsw/outsd */ |
2674 | c->src.bytes = min(c->src.bytes, 4u); | ||
2034 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], | 2675 | if (!emulator_io_permited(ctxt, ops, c->regs[VCPU_REGS_RDX], |
2035 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | 2676 | c->src.bytes)) { |
2036 | kvm_inject_gp(ctxt->vcpu, 0); | 2677 | kvm_inject_gp(ctxt->vcpu, 0); |
2037 | goto done; | 2678 | goto done; |
2038 | } | 2679 | } |
2039 | if (kvm_emulate_pio_string(ctxt->vcpu, | 2680 | ops->pio_out_emulated(c->src.bytes, c->regs[VCPU_REGS_RDX], |
2040 | 0, | 2681 | &c->src.val, 1, ctxt->vcpu); |
2041 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2682 | |
2042 | c->rep_prefix ? | 2683 | c->dst.type = OP_NONE; /* nothing to writeback */ |
2043 | address_mask(c, c->regs[VCPU_REGS_RCX]) : 1, | 2684 | break; |
2044 | (ctxt->eflags & EFLG_DF), | ||
2045 | register_address(c, | ||
2046 | seg_override_base(ctxt, c), | ||
2047 | c->regs[VCPU_REGS_RSI]), | ||
2048 | c->rep_prefix, | ||
2049 | c->regs[VCPU_REGS_RDX]) == 0) { | ||
2050 | c->eip = saved_eip; | ||
2051 | return -1; | ||
2052 | } | ||
2053 | return 0; | ||
2054 | case 0x70 ... 0x7f: /* jcc (short) */ | 2685 | case 0x70 ... 0x7f: /* jcc (short) */ |
2055 | if (test_cc(c->b, ctxt->eflags)) | 2686 | if (test_cc(c->b, ctxt->eflags)) |
2056 | jmp_rel(c, c->src.val); | 2687 | jmp_rel(c, c->src.val); |
@@ -2107,12 +2738,11 @@ special_insn: | |||
2107 | case 0x8c: { /* mov r/m, sreg */ | 2738 | case 0x8c: { /* mov r/m, sreg */ |
2108 | struct kvm_segment segreg; | 2739 | struct kvm_segment segreg; |
2109 | 2740 | ||
2110 | if (c->modrm_reg <= 5) | 2741 | if (c->modrm_reg <= VCPU_SREG_GS) |
2111 | kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg); | 2742 | kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg); |
2112 | else { | 2743 | else { |
2113 | printk(KERN_INFO "0x8c: Invalid segreg in modrm byte 0x%02x\n", | 2744 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
2114 | c->modrm); | 2745 | goto done; |
2115 | goto cannot_emulate; | ||
2116 | } | 2746 | } |
2117 | c->dst.val = segreg.selector; | 2747 | c->dst.val = segreg.selector; |
2118 | break; | 2748 | break; |
@@ -2132,16 +2762,16 @@ special_insn: | |||
2132 | } | 2762 | } |
2133 | 2763 | ||
2134 | if (c->modrm_reg == VCPU_SREG_SS) | 2764 | if (c->modrm_reg == VCPU_SREG_SS) |
2135 | toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS); | 2765 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_MOV_SS); |
2136 | 2766 | ||
2137 | rc = kvm_load_segment_descriptor(ctxt->vcpu, sel, c->modrm_reg); | 2767 | rc = load_segment_descriptor(ctxt, ops, sel, c->modrm_reg); |
2138 | 2768 | ||
2139 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2769 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2140 | break; | 2770 | break; |
2141 | } | 2771 | } |
2142 | case 0x8f: /* pop (sole member of Grp1a) */ | 2772 | case 0x8f: /* pop (sole member of Grp1a) */ |
2143 | rc = emulate_grp1a(ctxt, ops); | 2773 | rc = emulate_grp1a(ctxt, ops); |
2144 | if (rc != 0) | 2774 | if (rc != X86EMUL_CONTINUE) |
2145 | goto done; | 2775 | goto done; |
2146 | break; | 2776 | break; |
2147 | case 0x90: /* nop / xchg r8,rax */ | 2777 | case 0x90: /* nop / xchg r8,rax */ |
@@ -2175,89 +2805,16 @@ special_insn: | |||
2175 | c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; | 2805 | c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; |
2176 | break; | 2806 | break; |
2177 | case 0xa4 ... 0xa5: /* movs */ | 2807 | case 0xa4 ... 0xa5: /* movs */ |
2178 | c->dst.type = OP_MEM; | 2808 | goto mov; |
2179 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
2180 | c->dst.ptr = (unsigned long *)register_address(c, | ||
2181 | es_base(ctxt), | ||
2182 | c->regs[VCPU_REGS_RDI]); | ||
2183 | rc = ops->read_emulated(register_address(c, | ||
2184 | seg_override_base(ctxt, c), | ||
2185 | c->regs[VCPU_REGS_RSI]), | ||
2186 | &c->dst.val, | ||
2187 | c->dst.bytes, ctxt->vcpu); | ||
2188 | if (rc != X86EMUL_CONTINUE) | ||
2189 | goto done; | ||
2190 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | ||
2191 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | ||
2192 | : c->dst.bytes); | ||
2193 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], | ||
2194 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | ||
2195 | : c->dst.bytes); | ||
2196 | break; | ||
2197 | case 0xa6 ... 0xa7: /* cmps */ | 2809 | case 0xa6 ... 0xa7: /* cmps */ |
2198 | c->src.type = OP_NONE; /* Disable writeback. */ | ||
2199 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
2200 | c->src.ptr = (unsigned long *)register_address(c, | ||
2201 | seg_override_base(ctxt, c), | ||
2202 | c->regs[VCPU_REGS_RSI]); | ||
2203 | rc = ops->read_emulated((unsigned long)c->src.ptr, | ||
2204 | &c->src.val, | ||
2205 | c->src.bytes, | ||
2206 | ctxt->vcpu); | ||
2207 | if (rc != X86EMUL_CONTINUE) | ||
2208 | goto done; | ||
2209 | |||
2210 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2810 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2211 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
2212 | c->dst.ptr = (unsigned long *)register_address(c, | ||
2213 | es_base(ctxt), | ||
2214 | c->regs[VCPU_REGS_RDI]); | ||
2215 | rc = ops->read_emulated((unsigned long)c->dst.ptr, | ||
2216 | &c->dst.val, | ||
2217 | c->dst.bytes, | ||
2218 | ctxt->vcpu); | ||
2219 | if (rc != X86EMUL_CONTINUE) | ||
2220 | goto done; | ||
2221 | |||
2222 | DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); | 2811 | DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr); |
2223 | 2812 | goto cmp; | |
2224 | emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); | ||
2225 | |||
2226 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | ||
2227 | (ctxt->eflags & EFLG_DF) ? -c->src.bytes | ||
2228 | : c->src.bytes); | ||
2229 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], | ||
2230 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | ||
2231 | : c->dst.bytes); | ||
2232 | |||
2233 | break; | ||
2234 | case 0xaa ... 0xab: /* stos */ | 2813 | case 0xaa ... 0xab: /* stos */ |
2235 | c->dst.type = OP_MEM; | ||
2236 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
2237 | c->dst.ptr = (unsigned long *)register_address(c, | ||
2238 | es_base(ctxt), | ||
2239 | c->regs[VCPU_REGS_RDI]); | ||
2240 | c->dst.val = c->regs[VCPU_REGS_RAX]; | 2814 | c->dst.val = c->regs[VCPU_REGS_RAX]; |
2241 | register_address_increment(c, &c->regs[VCPU_REGS_RDI], | ||
2242 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | ||
2243 | : c->dst.bytes); | ||
2244 | break; | 2815 | break; |
2245 | case 0xac ... 0xad: /* lods */ | 2816 | case 0xac ... 0xad: /* lods */ |
2246 | c->dst.type = OP_REG; | 2817 | goto mov; |
2247 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | ||
2248 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; | ||
2249 | rc = ops->read_emulated(register_address(c, | ||
2250 | seg_override_base(ctxt, c), | ||
2251 | c->regs[VCPU_REGS_RSI]), | ||
2252 | &c->dst.val, | ||
2253 | c->dst.bytes, | ||
2254 | ctxt->vcpu); | ||
2255 | if (rc != X86EMUL_CONTINUE) | ||
2256 | goto done; | ||
2257 | register_address_increment(c, &c->regs[VCPU_REGS_RSI], | ||
2258 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes | ||
2259 | : c->dst.bytes); | ||
2260 | break; | ||
2261 | case 0xae ... 0xaf: /* scas */ | 2818 | case 0xae ... 0xaf: /* scas */ |
2262 | DPRINTF("Urk! I don't handle SCAS.\n"); | 2819 | DPRINTF("Urk! I don't handle SCAS.\n"); |
2263 | goto cannot_emulate; | 2820 | goto cannot_emulate; |
@@ -2277,7 +2834,7 @@ special_insn: | |||
2277 | break; | 2834 | break; |
2278 | case 0xcb: /* ret far */ | 2835 | case 0xcb: /* ret far */ |
2279 | rc = emulate_ret_far(ctxt, ops); | 2836 | rc = emulate_ret_far(ctxt, ops); |
2280 | if (rc) | 2837 | if (rc != X86EMUL_CONTINUE) |
2281 | goto done; | 2838 | goto done; |
2282 | break; | 2839 | break; |
2283 | case 0xd0 ... 0xd1: /* Grp2 */ | 2840 | case 0xd0 ... 0xd1: /* Grp2 */ |
@@ -2290,14 +2847,10 @@ special_insn: | |||
2290 | break; | 2847 | break; |
2291 | case 0xe4: /* inb */ | 2848 | case 0xe4: /* inb */ |
2292 | case 0xe5: /* in */ | 2849 | case 0xe5: /* in */ |
2293 | port = c->src.val; | 2850 | goto do_io_in; |
2294 | io_dir_in = 1; | ||
2295 | goto do_io; | ||
2296 | case 0xe6: /* outb */ | 2851 | case 0xe6: /* outb */ |
2297 | case 0xe7: /* out */ | 2852 | case 0xe7: /* out */ |
2298 | port = c->src.val; | 2853 | goto do_io_out; |
2299 | io_dir_in = 0; | ||
2300 | goto do_io; | ||
2301 | case 0xe8: /* call (near) */ { | 2854 | case 0xe8: /* call (near) */ { |
2302 | long int rel = c->src.val; | 2855 | long int rel = c->src.val; |
2303 | c->src.val = (unsigned long) c->eip; | 2856 | c->src.val = (unsigned long) c->eip; |
@@ -2308,8 +2861,9 @@ special_insn: | |||
2308 | case 0xe9: /* jmp rel */ | 2861 | case 0xe9: /* jmp rel */ |
2309 | goto jmp; | 2862 | goto jmp; |
2310 | case 0xea: /* jmp far */ | 2863 | case 0xea: /* jmp far */ |
2311 | if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, | 2864 | jump_far: |
2312 | VCPU_SREG_CS)) | 2865 | if (load_segment_descriptor(ctxt, ops, c->src2.val, |
2866 | VCPU_SREG_CS)) | ||
2313 | goto done; | 2867 | goto done; |
2314 | 2868 | ||
2315 | c->eip = c->src.val; | 2869 | c->eip = c->src.val; |
@@ -2321,25 +2875,29 @@ special_insn: | |||
2321 | break; | 2875 | break; |
2322 | case 0xec: /* in al,dx */ | 2876 | case 0xec: /* in al,dx */ |
2323 | case 0xed: /* in (e/r)ax,dx */ | 2877 | case 0xed: /* in (e/r)ax,dx */ |
2324 | port = c->regs[VCPU_REGS_RDX]; | 2878 | c->src.val = c->regs[VCPU_REGS_RDX]; |
2325 | io_dir_in = 1; | 2879 | do_io_in: |
2326 | goto do_io; | 2880 | c->dst.bytes = min(c->dst.bytes, 4u); |
2881 | if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { | ||
2882 | kvm_inject_gp(ctxt->vcpu, 0); | ||
2883 | goto done; | ||
2884 | } | ||
2885 | if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val, | ||
2886 | &c->dst.val)) | ||
2887 | goto done; /* IO is needed */ | ||
2888 | break; | ||
2327 | case 0xee: /* out al,dx */ | 2889 | case 0xee: /* out al,dx */ |
2328 | case 0xef: /* out (e/r)ax,dx */ | 2890 | case 0xef: /* out (e/r)ax,dx */ |
2329 | port = c->regs[VCPU_REGS_RDX]; | 2891 | c->src.val = c->regs[VCPU_REGS_RDX]; |
2330 | io_dir_in = 0; | 2892 | do_io_out: |
2331 | do_io: | 2893 | c->dst.bytes = min(c->dst.bytes, 4u); |
2332 | if (!emulator_io_permited(ctxt, ops, port, | 2894 | if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) { |
2333 | (c->d & ByteOp) ? 1 : c->op_bytes)) { | ||
2334 | kvm_inject_gp(ctxt->vcpu, 0); | 2895 | kvm_inject_gp(ctxt->vcpu, 0); |
2335 | goto done; | 2896 | goto done; |
2336 | } | 2897 | } |
2337 | if (kvm_emulate_pio(ctxt->vcpu, io_dir_in, | 2898 | ops->pio_out_emulated(c->dst.bytes, c->src.val, &c->dst.val, 1, |
2338 | (c->d & ByteOp) ? 1 : c->op_bytes, | 2899 | ctxt->vcpu); |
2339 | port) != 0) { | 2900 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2340 | c->eip = saved_eip; | ||
2341 | goto cannot_emulate; | ||
2342 | } | ||
2343 | break; | 2901 | break; |
2344 | case 0xf4: /* hlt */ | 2902 | case 0xf4: /* hlt */ |
2345 | ctxt->vcpu->arch.halt_request = 1; | 2903 | ctxt->vcpu->arch.halt_request = 1; |
@@ -2350,16 +2908,15 @@ special_insn: | |||
2350 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2908 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2351 | break; | 2909 | break; |
2352 | case 0xf6 ... 0xf7: /* Grp3 */ | 2910 | case 0xf6 ... 0xf7: /* Grp3 */ |
2353 | rc = emulate_grp3(ctxt, ops); | 2911 | if (!emulate_grp3(ctxt, ops)) |
2354 | if (rc != 0) | 2912 | goto cannot_emulate; |
2355 | goto done; | ||
2356 | break; | 2913 | break; |
2357 | case 0xf8: /* clc */ | 2914 | case 0xf8: /* clc */ |
2358 | ctxt->eflags &= ~EFLG_CF; | 2915 | ctxt->eflags &= ~EFLG_CF; |
2359 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2916 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2360 | break; | 2917 | break; |
2361 | case 0xfa: /* cli */ | 2918 | case 0xfa: /* cli */ |
2362 | if (emulator_bad_iopl(ctxt)) | 2919 | if (emulator_bad_iopl(ctxt, ops)) |
2363 | kvm_inject_gp(ctxt->vcpu, 0); | 2920 | kvm_inject_gp(ctxt->vcpu, 0); |
2364 | else { | 2921 | else { |
2365 | ctxt->eflags &= ~X86_EFLAGS_IF; | 2922 | ctxt->eflags &= ~X86_EFLAGS_IF; |
@@ -2367,10 +2924,10 @@ special_insn: | |||
2367 | } | 2924 | } |
2368 | break; | 2925 | break; |
2369 | case 0xfb: /* sti */ | 2926 | case 0xfb: /* sti */ |
2370 | if (emulator_bad_iopl(ctxt)) | 2927 | if (emulator_bad_iopl(ctxt, ops)) |
2371 | kvm_inject_gp(ctxt->vcpu, 0); | 2928 | kvm_inject_gp(ctxt->vcpu, 0); |
2372 | else { | 2929 | else { |
2373 | toggle_interruptibility(ctxt, X86_SHADOW_INT_STI); | 2930 | toggle_interruptibility(ctxt, KVM_X86_SHADOW_INT_STI); |
2374 | ctxt->eflags |= X86_EFLAGS_IF; | 2931 | ctxt->eflags |= X86_EFLAGS_IF; |
2375 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2932 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2376 | } | 2933 | } |
@@ -2383,28 +2940,55 @@ special_insn: | |||
2383 | ctxt->eflags |= EFLG_DF; | 2940 | ctxt->eflags |= EFLG_DF; |
2384 | c->dst.type = OP_NONE; /* Disable writeback. */ | 2941 | c->dst.type = OP_NONE; /* Disable writeback. */ |
2385 | break; | 2942 | break; |
2386 | case 0xfe ... 0xff: /* Grp4/Grp5 */ | 2943 | case 0xfe: /* Grp4 */ |
2944 | grp45: | ||
2387 | rc = emulate_grp45(ctxt, ops); | 2945 | rc = emulate_grp45(ctxt, ops); |
2388 | if (rc != 0) | 2946 | if (rc != X86EMUL_CONTINUE) |
2389 | goto done; | 2947 | goto done; |
2390 | break; | 2948 | break; |
2949 | case 0xff: /* Grp5 */ | ||
2950 | if (c->modrm_reg == 5) | ||
2951 | goto jump_far; | ||
2952 | goto grp45; | ||
2391 | } | 2953 | } |
2392 | 2954 | ||
2393 | writeback: | 2955 | writeback: |
2394 | rc = writeback(ctxt, ops); | 2956 | rc = writeback(ctxt, ops); |
2395 | if (rc != 0) | 2957 | if (rc != X86EMUL_CONTINUE) |
2396 | goto done; | 2958 | goto done; |
2397 | 2959 | ||
2960 | /* | ||
2961 | * restore dst type in case the decoding will be reused | ||
2962 | * (happens for string instruction ) | ||
2963 | */ | ||
2964 | c->dst.type = saved_dst_type; | ||
2965 | |||
2966 | if ((c->d & SrcMask) == SrcSI) | ||
2967 | string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI, | ||
2968 | &c->src); | ||
2969 | |||
2970 | if ((c->d & DstMask) == DstDI) | ||
2971 | string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst); | ||
2972 | |||
2973 | if (c->rep_prefix && (c->d & String)) { | ||
2974 | struct read_cache *rc = &ctxt->decode.io_read; | ||
2975 | register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); | ||
2976 | /* | ||
2977 | * Re-enter guest when pio read ahead buffer is empty or, | ||
2978 | * if it is not used, after each 1024 iteration. | ||
2979 | */ | ||
2980 | if ((rc->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) || | ||
2981 | (rc->end != 0 && rc->end == rc->pos)) | ||
2982 | ctxt->restart = false; | ||
2983 | } | ||
2984 | |||
2398 | /* Commit shadow register state. */ | 2985 | /* Commit shadow register state. */ |
2399 | memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); | 2986 | memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); |
2400 | kvm_rip_write(ctxt->vcpu, c->eip); | 2987 | kvm_rip_write(ctxt->vcpu, c->eip); |
2988 | ops->set_rflags(ctxt->vcpu, ctxt->eflags); | ||
2401 | 2989 | ||
2402 | done: | 2990 | done: |
2403 | if (rc == X86EMUL_UNHANDLEABLE) { | 2991 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; |
2404 | c->eip = saved_eip; | ||
2405 | return -1; | ||
2406 | } | ||
2407 | return 0; | ||
2408 | 2992 | ||
2409 | twobyte_insn: | 2993 | twobyte_insn: |
2410 | switch (c->b) { | 2994 | switch (c->b) { |
@@ -2418,18 +3002,18 @@ twobyte_insn: | |||
2418 | goto cannot_emulate; | 3002 | goto cannot_emulate; |
2419 | 3003 | ||
2420 | rc = kvm_fix_hypercall(ctxt->vcpu); | 3004 | rc = kvm_fix_hypercall(ctxt->vcpu); |
2421 | if (rc) | 3005 | if (rc != X86EMUL_CONTINUE) |
2422 | goto done; | 3006 | goto done; |
2423 | 3007 | ||
2424 | /* Let the processor re-execute the fixed hypercall */ | 3008 | /* Let the processor re-execute the fixed hypercall */ |
2425 | c->eip = kvm_rip_read(ctxt->vcpu); | 3009 | c->eip = ctxt->eip; |
2426 | /* Disable writeback. */ | 3010 | /* Disable writeback. */ |
2427 | c->dst.type = OP_NONE; | 3011 | c->dst.type = OP_NONE; |
2428 | break; | 3012 | break; |
2429 | case 2: /* lgdt */ | 3013 | case 2: /* lgdt */ |
2430 | rc = read_descriptor(ctxt, ops, c->src.ptr, | 3014 | rc = read_descriptor(ctxt, ops, c->src.ptr, |
2431 | &size, &address, c->op_bytes); | 3015 | &size, &address, c->op_bytes); |
2432 | if (rc) | 3016 | if (rc != X86EMUL_CONTINUE) |
2433 | goto done; | 3017 | goto done; |
2434 | realmode_lgdt(ctxt->vcpu, size, address); | 3018 | realmode_lgdt(ctxt->vcpu, size, address); |
2435 | /* Disable writeback. */ | 3019 | /* Disable writeback. */ |
@@ -2440,7 +3024,7 @@ twobyte_insn: | |||
2440 | switch (c->modrm_rm) { | 3024 | switch (c->modrm_rm) { |
2441 | case 1: | 3025 | case 1: |
2442 | rc = kvm_fix_hypercall(ctxt->vcpu); | 3026 | rc = kvm_fix_hypercall(ctxt->vcpu); |
2443 | if (rc) | 3027 | if (rc != X86EMUL_CONTINUE) |
2444 | goto done; | 3028 | goto done; |
2445 | break; | 3029 | break; |
2446 | default: | 3030 | default: |
@@ -2450,7 +3034,7 @@ twobyte_insn: | |||
2450 | rc = read_descriptor(ctxt, ops, c->src.ptr, | 3034 | rc = read_descriptor(ctxt, ops, c->src.ptr, |
2451 | &size, &address, | 3035 | &size, &address, |
2452 | c->op_bytes); | 3036 | c->op_bytes); |
2453 | if (rc) | 3037 | if (rc != X86EMUL_CONTINUE) |
2454 | goto done; | 3038 | goto done; |
2455 | realmode_lidt(ctxt->vcpu, size, address); | 3039 | realmode_lidt(ctxt->vcpu, size, address); |
2456 | } | 3040 | } |
@@ -2459,15 +3043,18 @@ twobyte_insn: | |||
2459 | break; | 3043 | break; |
2460 | case 4: /* smsw */ | 3044 | case 4: /* smsw */ |
2461 | c->dst.bytes = 2; | 3045 | c->dst.bytes = 2; |
2462 | c->dst.val = realmode_get_cr(ctxt->vcpu, 0); | 3046 | c->dst.val = ops->get_cr(0, ctxt->vcpu); |
2463 | break; | 3047 | break; |
2464 | case 6: /* lmsw */ | 3048 | case 6: /* lmsw */ |
2465 | realmode_lmsw(ctxt->vcpu, (u16)c->src.val, | 3049 | ops->set_cr(0, (ops->get_cr(0, ctxt->vcpu) & ~0x0ful) | |
2466 | &ctxt->eflags); | 3050 | (c->src.val & 0x0f), ctxt->vcpu); |
2467 | c->dst.type = OP_NONE; | 3051 | c->dst.type = OP_NONE; |
2468 | break; | 3052 | break; |
3053 | case 5: /* not defined */ | ||
3054 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
3055 | goto done; | ||
2469 | case 7: /* invlpg*/ | 3056 | case 7: /* invlpg*/ |
2470 | emulate_invlpg(ctxt->vcpu, memop); | 3057 | emulate_invlpg(ctxt->vcpu, c->modrm_ea); |
2471 | /* Disable writeback. */ | 3058 | /* Disable writeback. */ |
2472 | c->dst.type = OP_NONE; | 3059 | c->dst.type = OP_NONE; |
2473 | break; | 3060 | break; |
@@ -2493,54 +3080,54 @@ twobyte_insn: | |||
2493 | c->dst.type = OP_NONE; | 3080 | c->dst.type = OP_NONE; |
2494 | break; | 3081 | break; |
2495 | case 0x20: /* mov cr, reg */ | 3082 | case 0x20: /* mov cr, reg */ |
2496 | if (c->modrm_mod != 3) | 3083 | switch (c->modrm_reg) { |
2497 | goto cannot_emulate; | 3084 | case 1: |
2498 | c->regs[c->modrm_rm] = | 3085 | case 5 ... 7: |
2499 | realmode_get_cr(ctxt->vcpu, c->modrm_reg); | 3086 | case 9 ... 15: |
3087 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); | ||
3088 | goto done; | ||
3089 | } | ||
3090 | c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu); | ||
2500 | c->dst.type = OP_NONE; /* no writeback */ | 3091 | c->dst.type = OP_NONE; /* no writeback */ |
2501 | break; | 3092 | break; |
2502 | case 0x21: /* mov from dr to reg */ | 3093 | case 0x21: /* mov from dr to reg */ |
2503 | if (c->modrm_mod != 3) | 3094 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && |
2504 | goto cannot_emulate; | 3095 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { |
2505 | rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); | 3096 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
2506 | if (rc) | 3097 | goto done; |
2507 | goto cannot_emulate; | 3098 | } |
3099 | emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]); | ||
2508 | c->dst.type = OP_NONE; /* no writeback */ | 3100 | c->dst.type = OP_NONE; /* no writeback */ |
2509 | break; | 3101 | break; |
2510 | case 0x22: /* mov reg, cr */ | 3102 | case 0x22: /* mov reg, cr */ |
2511 | if (c->modrm_mod != 3) | 3103 | ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu); |
2512 | goto cannot_emulate; | ||
2513 | realmode_set_cr(ctxt->vcpu, | ||
2514 | c->modrm_reg, c->modrm_val, &ctxt->eflags); | ||
2515 | c->dst.type = OP_NONE; | 3104 | c->dst.type = OP_NONE; |
2516 | break; | 3105 | break; |
2517 | case 0x23: /* mov from reg to dr */ | 3106 | case 0x23: /* mov from reg to dr */ |
2518 | if (c->modrm_mod != 3) | 3107 | if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) && |
2519 | goto cannot_emulate; | 3108 | (c->modrm_reg == 4 || c->modrm_reg == 5)) { |
2520 | rc = emulator_set_dr(ctxt, c->modrm_reg, | 3109 | kvm_queue_exception(ctxt->vcpu, UD_VECTOR); |
2521 | c->regs[c->modrm_rm]); | 3110 | goto done; |
2522 | if (rc) | 3111 | } |
2523 | goto cannot_emulate; | 3112 | emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm]); |
2524 | c->dst.type = OP_NONE; /* no writeback */ | 3113 | c->dst.type = OP_NONE; /* no writeback */ |
2525 | break; | 3114 | break; |
2526 | case 0x30: | 3115 | case 0x30: |
2527 | /* wrmsr */ | 3116 | /* wrmsr */ |
2528 | msr_data = (u32)c->regs[VCPU_REGS_RAX] | 3117 | msr_data = (u32)c->regs[VCPU_REGS_RAX] |
2529 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); | 3118 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); |
2530 | rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); | 3119 | if (kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) { |
2531 | if (rc) { | ||
2532 | kvm_inject_gp(ctxt->vcpu, 0); | 3120 | kvm_inject_gp(ctxt->vcpu, 0); |
2533 | c->eip = kvm_rip_read(ctxt->vcpu); | 3121 | goto done; |
2534 | } | 3122 | } |
2535 | rc = X86EMUL_CONTINUE; | 3123 | rc = X86EMUL_CONTINUE; |
2536 | c->dst.type = OP_NONE; | 3124 | c->dst.type = OP_NONE; |
2537 | break; | 3125 | break; |
2538 | case 0x32: | 3126 | case 0x32: |
2539 | /* rdmsr */ | 3127 | /* rdmsr */ |
2540 | rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data); | 3128 | if (kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) { |
2541 | if (rc) { | ||
2542 | kvm_inject_gp(ctxt->vcpu, 0); | 3129 | kvm_inject_gp(ctxt->vcpu, 0); |
2543 | c->eip = kvm_rip_read(ctxt->vcpu); | 3130 | goto done; |
2544 | } else { | 3131 | } else { |
2545 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; | 3132 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; |
2546 | c->regs[VCPU_REGS_RDX] = msr_data >> 32; | 3133 | c->regs[VCPU_REGS_RDX] = msr_data >> 32; |
@@ -2577,7 +3164,7 @@ twobyte_insn: | |||
2577 | break; | 3164 | break; |
2578 | case 0xa1: /* pop fs */ | 3165 | case 0xa1: /* pop fs */ |
2579 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS); | 3166 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS); |
2580 | if (rc != 0) | 3167 | if (rc != X86EMUL_CONTINUE) |
2581 | goto done; | 3168 | goto done; |
2582 | break; | 3169 | break; |
2583 | case 0xa3: | 3170 | case 0xa3: |
@@ -2596,7 +3183,7 @@ twobyte_insn: | |||
2596 | break; | 3183 | break; |
2597 | case 0xa9: /* pop gs */ | 3184 | case 0xa9: /* pop gs */ |
2598 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS); | 3185 | rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS); |
2599 | if (rc != 0) | 3186 | if (rc != X86EMUL_CONTINUE) |
2600 | goto done; | 3187 | goto done; |
2601 | break; | 3188 | break; |
2602 | case 0xab: | 3189 | case 0xab: |
@@ -2668,16 +3255,14 @@ twobyte_insn: | |||
2668 | (u64) c->src.val; | 3255 | (u64) c->src.val; |
2669 | break; | 3256 | break; |
2670 | case 0xc7: /* Grp9 (cmpxchg8b) */ | 3257 | case 0xc7: /* Grp9 (cmpxchg8b) */ |
2671 | rc = emulate_grp9(ctxt, ops, memop); | 3258 | rc = emulate_grp9(ctxt, ops); |
2672 | if (rc != 0) | 3259 | if (rc != X86EMUL_CONTINUE) |
2673 | goto done; | 3260 | goto done; |
2674 | c->dst.type = OP_NONE; | ||
2675 | break; | 3261 | break; |
2676 | } | 3262 | } |
2677 | goto writeback; | 3263 | goto writeback; |
2678 | 3264 | ||
2679 | cannot_emulate: | 3265 | cannot_emulate: |
2680 | DPRINTF("Cannot emulate %02x\n", c->b); | 3266 | DPRINTF("Cannot emulate %02x\n", c->b); |
2681 | c->eip = saved_eip; | ||
2682 | return -1; | 3267 | return -1; |
2683 | } | 3268 | } |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index a790fa128a9f..93825ff3338f 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -33,6 +33,29 @@ | |||
33 | #include <linux/kvm_host.h> | 33 | #include <linux/kvm_host.h> |
34 | #include "trace.h" | 34 | #include "trace.h" |
35 | 35 | ||
36 | static void pic_lock(struct kvm_pic *s) | ||
37 | __acquires(&s->lock) | ||
38 | { | ||
39 | raw_spin_lock(&s->lock); | ||
40 | } | ||
41 | |||
42 | static void pic_unlock(struct kvm_pic *s) | ||
43 | __releases(&s->lock) | ||
44 | { | ||
45 | bool wakeup = s->wakeup_needed; | ||
46 | struct kvm_vcpu *vcpu; | ||
47 | |||
48 | s->wakeup_needed = false; | ||
49 | |||
50 | raw_spin_unlock(&s->lock); | ||
51 | |||
52 | if (wakeup) { | ||
53 | vcpu = s->kvm->bsp_vcpu; | ||
54 | if (vcpu) | ||
55 | kvm_vcpu_kick(vcpu); | ||
56 | } | ||
57 | } | ||
58 | |||
36 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) | 59 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) |
37 | { | 60 | { |
38 | s->isr &= ~(1 << irq); | 61 | s->isr &= ~(1 << irq); |
@@ -45,19 +68,19 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq) | |||
45 | * Other interrupt may be delivered to PIC while lock is dropped but | 68 | * Other interrupt may be delivered to PIC while lock is dropped but |
46 | * it should be safe since PIC state is already updated at this stage. | 69 | * it should be safe since PIC state is already updated at this stage. |
47 | */ | 70 | */ |
48 | raw_spin_unlock(&s->pics_state->lock); | 71 | pic_unlock(s->pics_state); |
49 | kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); | 72 | kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); |
50 | raw_spin_lock(&s->pics_state->lock); | 73 | pic_lock(s->pics_state); |
51 | } | 74 | } |
52 | 75 | ||
53 | void kvm_pic_clear_isr_ack(struct kvm *kvm) | 76 | void kvm_pic_clear_isr_ack(struct kvm *kvm) |
54 | { | 77 | { |
55 | struct kvm_pic *s = pic_irqchip(kvm); | 78 | struct kvm_pic *s = pic_irqchip(kvm); |
56 | 79 | ||
57 | raw_spin_lock(&s->lock); | 80 | pic_lock(s); |
58 | s->pics[0].isr_ack = 0xff; | 81 | s->pics[0].isr_ack = 0xff; |
59 | s->pics[1].isr_ack = 0xff; | 82 | s->pics[1].isr_ack = 0xff; |
60 | raw_spin_unlock(&s->lock); | 83 | pic_unlock(s); |
61 | } | 84 | } |
62 | 85 | ||
63 | /* | 86 | /* |
@@ -158,9 +181,9 @@ static void pic_update_irq(struct kvm_pic *s) | |||
158 | 181 | ||
159 | void kvm_pic_update_irq(struct kvm_pic *s) | 182 | void kvm_pic_update_irq(struct kvm_pic *s) |
160 | { | 183 | { |
161 | raw_spin_lock(&s->lock); | 184 | pic_lock(s); |
162 | pic_update_irq(s); | 185 | pic_update_irq(s); |
163 | raw_spin_unlock(&s->lock); | 186 | pic_unlock(s); |
164 | } | 187 | } |
165 | 188 | ||
166 | int kvm_pic_set_irq(void *opaque, int irq, int level) | 189 | int kvm_pic_set_irq(void *opaque, int irq, int level) |
@@ -168,14 +191,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level) | |||
168 | struct kvm_pic *s = opaque; | 191 | struct kvm_pic *s = opaque; |
169 | int ret = -1; | 192 | int ret = -1; |
170 | 193 | ||
171 | raw_spin_lock(&s->lock); | 194 | pic_lock(s); |
172 | if (irq >= 0 && irq < PIC_NUM_PINS) { | 195 | if (irq >= 0 && irq < PIC_NUM_PINS) { |
173 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); | 196 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); |
174 | pic_update_irq(s); | 197 | pic_update_irq(s); |
175 | trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, | 198 | trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, |
176 | s->pics[irq >> 3].imr, ret == 0); | 199 | s->pics[irq >> 3].imr, ret == 0); |
177 | } | 200 | } |
178 | raw_spin_unlock(&s->lock); | 201 | pic_unlock(s); |
179 | 202 | ||
180 | return ret; | 203 | return ret; |
181 | } | 204 | } |
@@ -205,7 +228,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
205 | int irq, irq2, intno; | 228 | int irq, irq2, intno; |
206 | struct kvm_pic *s = pic_irqchip(kvm); | 229 | struct kvm_pic *s = pic_irqchip(kvm); |
207 | 230 | ||
208 | raw_spin_lock(&s->lock); | 231 | pic_lock(s); |
209 | irq = pic_get_irq(&s->pics[0]); | 232 | irq = pic_get_irq(&s->pics[0]); |
210 | if (irq >= 0) { | 233 | if (irq >= 0) { |
211 | pic_intack(&s->pics[0], irq); | 234 | pic_intack(&s->pics[0], irq); |
@@ -230,7 +253,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
230 | intno = s->pics[0].irq_base + irq; | 253 | intno = s->pics[0].irq_base + irq; |
231 | } | 254 | } |
232 | pic_update_irq(s); | 255 | pic_update_irq(s); |
233 | raw_spin_unlock(&s->lock); | 256 | pic_unlock(s); |
234 | 257 | ||
235 | return intno; | 258 | return intno; |
236 | } | 259 | } |
@@ -444,7 +467,7 @@ static int picdev_write(struct kvm_io_device *this, | |||
444 | printk(KERN_ERR "PIC: non byte write\n"); | 467 | printk(KERN_ERR "PIC: non byte write\n"); |
445 | return 0; | 468 | return 0; |
446 | } | 469 | } |
447 | raw_spin_lock(&s->lock); | 470 | pic_lock(s); |
448 | switch (addr) { | 471 | switch (addr) { |
449 | case 0x20: | 472 | case 0x20: |
450 | case 0x21: | 473 | case 0x21: |
@@ -457,7 +480,7 @@ static int picdev_write(struct kvm_io_device *this, | |||
457 | elcr_ioport_write(&s->pics[addr & 1], addr, data); | 480 | elcr_ioport_write(&s->pics[addr & 1], addr, data); |
458 | break; | 481 | break; |
459 | } | 482 | } |
460 | raw_spin_unlock(&s->lock); | 483 | pic_unlock(s); |
461 | return 0; | 484 | return 0; |
462 | } | 485 | } |
463 | 486 | ||
@@ -474,7 +497,7 @@ static int picdev_read(struct kvm_io_device *this, | |||
474 | printk(KERN_ERR "PIC: non byte read\n"); | 497 | printk(KERN_ERR "PIC: non byte read\n"); |
475 | return 0; | 498 | return 0; |
476 | } | 499 | } |
477 | raw_spin_lock(&s->lock); | 500 | pic_lock(s); |
478 | switch (addr) { | 501 | switch (addr) { |
479 | case 0x20: | 502 | case 0x20: |
480 | case 0x21: | 503 | case 0x21: |
@@ -488,7 +511,7 @@ static int picdev_read(struct kvm_io_device *this, | |||
488 | break; | 511 | break; |
489 | } | 512 | } |
490 | *(unsigned char *)val = data; | 513 | *(unsigned char *)val = data; |
491 | raw_spin_unlock(&s->lock); | 514 | pic_unlock(s); |
492 | return 0; | 515 | return 0; |
493 | } | 516 | } |
494 | 517 | ||
@@ -505,7 +528,7 @@ static void pic_irq_request(void *opaque, int level) | |||
505 | s->output = level; | 528 | s->output = level; |
506 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { | 529 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { |
507 | s->pics[0].isr_ack &= ~(1 << irq); | 530 | s->pics[0].isr_ack &= ~(1 << irq); |
508 | kvm_vcpu_kick(vcpu); | 531 | s->wakeup_needed = true; |
509 | } | 532 | } |
510 | } | 533 | } |
511 | 534 | ||
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 34b15915754d..cd1f362f413d 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -63,6 +63,7 @@ struct kvm_kpic_state { | |||
63 | 63 | ||
64 | struct kvm_pic { | 64 | struct kvm_pic { |
65 | raw_spinlock_t lock; | 65 | raw_spinlock_t lock; |
66 | bool wakeup_needed; | ||
66 | unsigned pending_acks; | 67 | unsigned pending_acks; |
67 | struct kvm *kvm; | 68 | struct kvm *kvm; |
68 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ | 69 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ |
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h index 55c7524dda54..64bc6ea78d90 100644 --- a/arch/x86/kvm/kvm_timer.h +++ b/arch/x86/kvm/kvm_timer.h | |||
@@ -10,9 +10,7 @@ struct kvm_timer { | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | struct kvm_timer_ops { | 12 | struct kvm_timer_ops { |
13 | bool (*is_periodic)(struct kvm_timer *); | 13 | bool (*is_periodic)(struct kvm_timer *); |
14 | }; | 14 | }; |
15 | 15 | ||
16 | |||
17 | enum hrtimer_restart kvm_timer_fn(struct hrtimer *data); | 16 | enum hrtimer_restart kvm_timer_fn(struct hrtimer *data); |
18 | |||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 48aeee8eefb0..7a17db1cdcd6 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -148,7 +148,6 @@ module_param(oos_shadow, bool, 0644); | |||
148 | 148 | ||
149 | #include <trace/events/kvm.h> | 149 | #include <trace/events/kvm.h> |
150 | 150 | ||
151 | #undef TRACE_INCLUDE_FILE | ||
152 | #define CREATE_TRACE_POINTS | 151 | #define CREATE_TRACE_POINTS |
153 | #include "mmutrace.h" | 152 | #include "mmutrace.h" |
154 | 153 | ||
@@ -174,12 +173,7 @@ struct kvm_shadow_walk_iterator { | |||
174 | shadow_walk_okay(&(_walker)); \ | 173 | shadow_walk_okay(&(_walker)); \ |
175 | shadow_walk_next(&(_walker))) | 174 | shadow_walk_next(&(_walker))) |
176 | 175 | ||
177 | 176 | typedef int (*mmu_parent_walk_fn) (struct kvm_mmu_page *sp); | |
178 | struct kvm_unsync_walk { | ||
179 | int (*entry) (struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk); | ||
180 | }; | ||
181 | |||
182 | typedef int (*mmu_parent_walk_fn) (struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp); | ||
183 | 177 | ||
184 | static struct kmem_cache *pte_chain_cache; | 178 | static struct kmem_cache *pte_chain_cache; |
185 | static struct kmem_cache *rmap_desc_cache; | 179 | static struct kmem_cache *rmap_desc_cache; |
@@ -327,7 +321,6 @@ static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, | |||
327 | page = alloc_page(GFP_KERNEL); | 321 | page = alloc_page(GFP_KERNEL); |
328 | if (!page) | 322 | if (!page) |
329 | return -ENOMEM; | 323 | return -ENOMEM; |
330 | set_page_private(page, 0); | ||
331 | cache->objects[cache->nobjs++] = page_address(page); | 324 | cache->objects[cache->nobjs++] = page_address(page); |
332 | } | 325 | } |
333 | return 0; | 326 | return 0; |
@@ -925,7 +918,6 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, | |||
925 | sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); | 918 | sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache, PAGE_SIZE); |
926 | set_page_private(virt_to_page(sp->spt), (unsigned long)sp); | 919 | set_page_private(virt_to_page(sp->spt), (unsigned long)sp); |
927 | list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); | 920 | list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); |
928 | INIT_LIST_HEAD(&sp->oos_link); | ||
929 | bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); | 921 | bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); |
930 | sp->multimapped = 0; | 922 | sp->multimapped = 0; |
931 | sp->parent_pte = parent_pte; | 923 | sp->parent_pte = parent_pte; |
@@ -1009,8 +1001,7 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp, | |||
1009 | } | 1001 | } |
1010 | 1002 | ||
1011 | 1003 | ||
1012 | static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 1004 | static void mmu_parent_walk(struct kvm_mmu_page *sp, mmu_parent_walk_fn fn) |
1013 | mmu_parent_walk_fn fn) | ||
1014 | { | 1005 | { |
1015 | struct kvm_pte_chain *pte_chain; | 1006 | struct kvm_pte_chain *pte_chain; |
1016 | struct hlist_node *node; | 1007 | struct hlist_node *node; |
@@ -1019,8 +1010,8 @@ static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
1019 | 1010 | ||
1020 | if (!sp->multimapped && sp->parent_pte) { | 1011 | if (!sp->multimapped && sp->parent_pte) { |
1021 | parent_sp = page_header(__pa(sp->parent_pte)); | 1012 | parent_sp = page_header(__pa(sp->parent_pte)); |
1022 | fn(vcpu, parent_sp); | 1013 | fn(parent_sp); |
1023 | mmu_parent_walk(vcpu, parent_sp, fn); | 1014 | mmu_parent_walk(parent_sp, fn); |
1024 | return; | 1015 | return; |
1025 | } | 1016 | } |
1026 | hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) | 1017 | hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link) |
@@ -1028,8 +1019,8 @@ static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | |||
1028 | if (!pte_chain->parent_ptes[i]) | 1019 | if (!pte_chain->parent_ptes[i]) |
1029 | break; | 1020 | break; |
1030 | parent_sp = page_header(__pa(pte_chain->parent_ptes[i])); | 1021 | parent_sp = page_header(__pa(pte_chain->parent_ptes[i])); |
1031 | fn(vcpu, parent_sp); | 1022 | fn(parent_sp); |
1032 | mmu_parent_walk(vcpu, parent_sp, fn); | 1023 | mmu_parent_walk(parent_sp, fn); |
1033 | } | 1024 | } |
1034 | } | 1025 | } |
1035 | 1026 | ||
@@ -1066,16 +1057,15 @@ static void kvm_mmu_update_parents_unsync(struct kvm_mmu_page *sp) | |||
1066 | } | 1057 | } |
1067 | } | 1058 | } |
1068 | 1059 | ||
1069 | static int unsync_walk_fn(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | 1060 | static int unsync_walk_fn(struct kvm_mmu_page *sp) |
1070 | { | 1061 | { |
1071 | kvm_mmu_update_parents_unsync(sp); | 1062 | kvm_mmu_update_parents_unsync(sp); |
1072 | return 1; | 1063 | return 1; |
1073 | } | 1064 | } |
1074 | 1065 | ||
1075 | static void kvm_mmu_mark_parents_unsync(struct kvm_vcpu *vcpu, | 1066 | static void kvm_mmu_mark_parents_unsync(struct kvm_mmu_page *sp) |
1076 | struct kvm_mmu_page *sp) | ||
1077 | { | 1067 | { |
1078 | mmu_parent_walk(vcpu, sp, unsync_walk_fn); | 1068 | mmu_parent_walk(sp, unsync_walk_fn); |
1079 | kvm_mmu_update_parents_unsync(sp); | 1069 | kvm_mmu_update_parents_unsync(sp); |
1080 | } | 1070 | } |
1081 | 1071 | ||
@@ -1209,7 +1199,7 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp); | |||
1209 | 1199 | ||
1210 | static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | 1200 | static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) |
1211 | { | 1201 | { |
1212 | if (sp->role.glevels != vcpu->arch.mmu.root_level) { | 1202 | if (sp->role.cr4_pae != !!is_pae(vcpu)) { |
1213 | kvm_mmu_zap_page(vcpu->kvm, sp); | 1203 | kvm_mmu_zap_page(vcpu->kvm, sp); |
1214 | return 1; | 1204 | return 1; |
1215 | } | 1205 | } |
@@ -1331,6 +1321,8 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
1331 | role = vcpu->arch.mmu.base_role; | 1321 | role = vcpu->arch.mmu.base_role; |
1332 | role.level = level; | 1322 | role.level = level; |
1333 | role.direct = direct; | 1323 | role.direct = direct; |
1324 | if (role.direct) | ||
1325 | role.cr4_pae = 0; | ||
1334 | role.access = access; | 1326 | role.access = access; |
1335 | if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) { | 1327 | if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) { |
1336 | quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); | 1328 | quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); |
@@ -1351,7 +1343,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
1351 | mmu_page_add_parent_pte(vcpu, sp, parent_pte); | 1343 | mmu_page_add_parent_pte(vcpu, sp, parent_pte); |
1352 | if (sp->unsync_children) { | 1344 | if (sp->unsync_children) { |
1353 | set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); | 1345 | set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); |
1354 | kvm_mmu_mark_parents_unsync(vcpu, sp); | 1346 | kvm_mmu_mark_parents_unsync(sp); |
1355 | } | 1347 | } |
1356 | trace_kvm_mmu_get_page(sp, false); | 1348 | trace_kvm_mmu_get_page(sp, false); |
1357 | return sp; | 1349 | return sp; |
@@ -1490,8 +1482,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm, | |||
1490 | for_each_sp(pages, sp, parents, i) { | 1482 | for_each_sp(pages, sp, parents, i) { |
1491 | kvm_mmu_zap_page(kvm, sp); | 1483 | kvm_mmu_zap_page(kvm, sp); |
1492 | mmu_pages_clear_parents(&parents); | 1484 | mmu_pages_clear_parents(&parents); |
1485 | zapped++; | ||
1493 | } | 1486 | } |
1494 | zapped += pages.nr; | ||
1495 | kvm_mmu_pages_init(parent, &parents, &pages); | 1487 | kvm_mmu_pages_init(parent, &parents, &pages); |
1496 | } | 1488 | } |
1497 | 1489 | ||
@@ -1542,14 +1534,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages) | |||
1542 | */ | 1534 | */ |
1543 | 1535 | ||
1544 | if (used_pages > kvm_nr_mmu_pages) { | 1536 | if (used_pages > kvm_nr_mmu_pages) { |
1545 | while (used_pages > kvm_nr_mmu_pages) { | 1537 | while (used_pages > kvm_nr_mmu_pages && |
1538 | !list_empty(&kvm->arch.active_mmu_pages)) { | ||
1546 | struct kvm_mmu_page *page; | 1539 | struct kvm_mmu_page *page; |
1547 | 1540 | ||
1548 | page = container_of(kvm->arch.active_mmu_pages.prev, | 1541 | page = container_of(kvm->arch.active_mmu_pages.prev, |
1549 | struct kvm_mmu_page, link); | 1542 | struct kvm_mmu_page, link); |
1550 | kvm_mmu_zap_page(kvm, page); | 1543 | used_pages -= kvm_mmu_zap_page(kvm, page); |
1551 | used_pages--; | 1544 | used_pages--; |
1552 | } | 1545 | } |
1546 | kvm_nr_mmu_pages = used_pages; | ||
1553 | kvm->arch.n_free_mmu_pages = 0; | 1547 | kvm->arch.n_free_mmu_pages = 0; |
1554 | } | 1548 | } |
1555 | else | 1549 | else |
@@ -1571,13 +1565,14 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) | |||
1571 | r = 0; | 1565 | r = 0; |
1572 | index = kvm_page_table_hashfn(gfn); | 1566 | index = kvm_page_table_hashfn(gfn); |
1573 | bucket = &kvm->arch.mmu_page_hash[index]; | 1567 | bucket = &kvm->arch.mmu_page_hash[index]; |
1568 | restart: | ||
1574 | hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) | 1569 | hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) |
1575 | if (sp->gfn == gfn && !sp->role.direct) { | 1570 | if (sp->gfn == gfn && !sp->role.direct) { |
1576 | pgprintk("%s: gfn %lx role %x\n", __func__, gfn, | 1571 | pgprintk("%s: gfn %lx role %x\n", __func__, gfn, |
1577 | sp->role.word); | 1572 | sp->role.word); |
1578 | r = 1; | 1573 | r = 1; |
1579 | if (kvm_mmu_zap_page(kvm, sp)) | 1574 | if (kvm_mmu_zap_page(kvm, sp)) |
1580 | n = bucket->first; | 1575 | goto restart; |
1581 | } | 1576 | } |
1582 | return r; | 1577 | return r; |
1583 | } | 1578 | } |
@@ -1591,12 +1586,14 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn) | |||
1591 | 1586 | ||
1592 | index = kvm_page_table_hashfn(gfn); | 1587 | index = kvm_page_table_hashfn(gfn); |
1593 | bucket = &kvm->arch.mmu_page_hash[index]; | 1588 | bucket = &kvm->arch.mmu_page_hash[index]; |
1589 | restart: | ||
1594 | hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) { | 1590 | hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) { |
1595 | if (sp->gfn == gfn && !sp->role.direct | 1591 | if (sp->gfn == gfn && !sp->role.direct |
1596 | && !sp->role.invalid) { | 1592 | && !sp->role.invalid) { |
1597 | pgprintk("%s: zap %lx %x\n", | 1593 | pgprintk("%s: zap %lx %x\n", |
1598 | __func__, gfn, sp->role.word); | 1594 | __func__, gfn, sp->role.word); |
1599 | kvm_mmu_zap_page(kvm, sp); | 1595 | if (kvm_mmu_zap_page(kvm, sp)) |
1596 | goto restart; | ||
1600 | } | 1597 | } |
1601 | } | 1598 | } |
1602 | } | 1599 | } |
@@ -1762,7 +1759,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
1762 | ++vcpu->kvm->stat.mmu_unsync; | 1759 | ++vcpu->kvm->stat.mmu_unsync; |
1763 | sp->unsync = 1; | 1760 | sp->unsync = 1; |
1764 | 1761 | ||
1765 | kvm_mmu_mark_parents_unsync(vcpu, sp); | 1762 | kvm_mmu_mark_parents_unsync(sp); |
1766 | 1763 | ||
1767 | mmu_convert_notrap(sp); | 1764 | mmu_convert_notrap(sp); |
1768 | return 0; | 1765 | return 0; |
@@ -2296,13 +2293,19 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2296 | /* no rsvd bits for 2 level 4K page table entries */ | 2293 | /* no rsvd bits for 2 level 4K page table entries */ |
2297 | context->rsvd_bits_mask[0][1] = 0; | 2294 | context->rsvd_bits_mask[0][1] = 0; |
2298 | context->rsvd_bits_mask[0][0] = 0; | 2295 | context->rsvd_bits_mask[0][0] = 0; |
2296 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; | ||
2297 | |||
2298 | if (!is_pse(vcpu)) { | ||
2299 | context->rsvd_bits_mask[1][1] = 0; | ||
2300 | break; | ||
2301 | } | ||
2302 | |||
2299 | if (is_cpuid_PSE36()) | 2303 | if (is_cpuid_PSE36()) |
2300 | /* 36bits PSE 4MB page */ | 2304 | /* 36bits PSE 4MB page */ |
2301 | context->rsvd_bits_mask[1][1] = rsvd_bits(17, 21); | 2305 | context->rsvd_bits_mask[1][1] = rsvd_bits(17, 21); |
2302 | else | 2306 | else |
2303 | /* 32 bits PSE 4MB page */ | 2307 | /* 32 bits PSE 4MB page */ |
2304 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); | 2308 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); |
2305 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; | ||
2306 | break; | 2309 | break; |
2307 | case PT32E_ROOT_LEVEL: | 2310 | case PT32E_ROOT_LEVEL: |
2308 | context->rsvd_bits_mask[0][2] = | 2311 | context->rsvd_bits_mask[0][2] = |
@@ -2315,7 +2318,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2315 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2318 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
2316 | rsvd_bits(maxphyaddr, 62) | | 2319 | rsvd_bits(maxphyaddr, 62) | |
2317 | rsvd_bits(13, 20); /* large page */ | 2320 | rsvd_bits(13, 20); /* large page */ |
2318 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; | 2321 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; |
2319 | break; | 2322 | break; |
2320 | case PT64_ROOT_LEVEL: | 2323 | case PT64_ROOT_LEVEL: |
2321 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | | 2324 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | |
@@ -2333,7 +2336,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2333 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2336 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
2334 | rsvd_bits(maxphyaddr, 51) | | 2337 | rsvd_bits(maxphyaddr, 51) | |
2335 | rsvd_bits(13, 20); /* large page */ | 2338 | rsvd_bits(13, 20); /* large page */ |
2336 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; | 2339 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[0][0]; |
2337 | break; | 2340 | break; |
2338 | } | 2341 | } |
2339 | } | 2342 | } |
@@ -2435,7 +2438,7 @@ static int init_kvm_softmmu(struct kvm_vcpu *vcpu) | |||
2435 | else | 2438 | else |
2436 | r = paging32_init_context(vcpu); | 2439 | r = paging32_init_context(vcpu); |
2437 | 2440 | ||
2438 | vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level; | 2441 | vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); |
2439 | 2442 | ||
2440 | return r; | 2443 | return r; |
2441 | } | 2444 | } |
@@ -2524,7 +2527,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, | |||
2524 | } | 2527 | } |
2525 | 2528 | ||
2526 | ++vcpu->kvm->stat.mmu_pte_updated; | 2529 | ++vcpu->kvm->stat.mmu_pte_updated; |
2527 | if (sp->role.glevels == PT32_ROOT_LEVEL) | 2530 | if (!sp->role.cr4_pae) |
2528 | paging32_update_pte(vcpu, sp, spte, new); | 2531 | paging32_update_pte(vcpu, sp, spte, new); |
2529 | else | 2532 | else |
2530 | paging64_update_pte(vcpu, sp, spte, new); | 2533 | paging64_update_pte(vcpu, sp, spte, new); |
@@ -2559,36 +2562,11 @@ static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu) | |||
2559 | } | 2562 | } |
2560 | 2563 | ||
2561 | static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | 2564 | static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, |
2562 | const u8 *new, int bytes) | 2565 | u64 gpte) |
2563 | { | 2566 | { |
2564 | gfn_t gfn; | 2567 | gfn_t gfn; |
2565 | int r; | ||
2566 | u64 gpte = 0; | ||
2567 | pfn_t pfn; | 2568 | pfn_t pfn; |
2568 | 2569 | ||
2569 | if (bytes != 4 && bytes != 8) | ||
2570 | return; | ||
2571 | |||
2572 | /* | ||
2573 | * Assume that the pte write on a page table of the same type | ||
2574 | * as the current vcpu paging mode. This is nearly always true | ||
2575 | * (might be false while changing modes). Note it is verified later | ||
2576 | * by update_pte(). | ||
2577 | */ | ||
2578 | if (is_pae(vcpu)) { | ||
2579 | /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ | ||
2580 | if ((bytes == 4) && (gpa % 4 == 0)) { | ||
2581 | r = kvm_read_guest(vcpu->kvm, gpa & ~(u64)7, &gpte, 8); | ||
2582 | if (r) | ||
2583 | return; | ||
2584 | memcpy((void *)&gpte + (gpa % 8), new, 4); | ||
2585 | } else if ((bytes == 8) && (gpa % 8 == 0)) { | ||
2586 | memcpy((void *)&gpte, new, 8); | ||
2587 | } | ||
2588 | } else { | ||
2589 | if ((bytes == 4) && (gpa % 4 == 0)) | ||
2590 | memcpy((void *)&gpte, new, 4); | ||
2591 | } | ||
2592 | if (!is_present_gpte(gpte)) | 2570 | if (!is_present_gpte(gpte)) |
2593 | return; | 2571 | return; |
2594 | gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; | 2572 | gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; |
@@ -2637,10 +2615,46 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
2637 | int flooded = 0; | 2615 | int flooded = 0; |
2638 | int npte; | 2616 | int npte; |
2639 | int r; | 2617 | int r; |
2618 | int invlpg_counter; | ||
2640 | 2619 | ||
2641 | pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); | 2620 | pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); |
2642 | mmu_guess_page_from_pte_write(vcpu, gpa, new, bytes); | 2621 | |
2622 | invlpg_counter = atomic_read(&vcpu->kvm->arch.invlpg_counter); | ||
2623 | |||
2624 | /* | ||
2625 | * Assume that the pte write on a page table of the same type | ||
2626 | * as the current vcpu paging mode. This is nearly always true | ||
2627 | * (might be false while changing modes). Note it is verified later | ||
2628 | * by update_pte(). | ||
2629 | */ | ||
2630 | if ((is_pae(vcpu) && bytes == 4) || !new) { | ||
2631 | /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ | ||
2632 | if (is_pae(vcpu)) { | ||
2633 | gpa &= ~(gpa_t)7; | ||
2634 | bytes = 8; | ||
2635 | } | ||
2636 | r = kvm_read_guest(vcpu->kvm, gpa, &gentry, min(bytes, 8)); | ||
2637 | if (r) | ||
2638 | gentry = 0; | ||
2639 | new = (const u8 *)&gentry; | ||
2640 | } | ||
2641 | |||
2642 | switch (bytes) { | ||
2643 | case 4: | ||
2644 | gentry = *(const u32 *)new; | ||
2645 | break; | ||
2646 | case 8: | ||
2647 | gentry = *(const u64 *)new; | ||
2648 | break; | ||
2649 | default: | ||
2650 | gentry = 0; | ||
2651 | break; | ||
2652 | } | ||
2653 | |||
2654 | mmu_guess_page_from_pte_write(vcpu, gpa, gentry); | ||
2643 | spin_lock(&vcpu->kvm->mmu_lock); | 2655 | spin_lock(&vcpu->kvm->mmu_lock); |
2656 | if (atomic_read(&vcpu->kvm->arch.invlpg_counter) != invlpg_counter) | ||
2657 | gentry = 0; | ||
2644 | kvm_mmu_access_page(vcpu, gfn); | 2658 | kvm_mmu_access_page(vcpu, gfn); |
2645 | kvm_mmu_free_some_pages(vcpu); | 2659 | kvm_mmu_free_some_pages(vcpu); |
2646 | ++vcpu->kvm->stat.mmu_pte_write; | 2660 | ++vcpu->kvm->stat.mmu_pte_write; |
@@ -2659,10 +2673,12 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
2659 | } | 2673 | } |
2660 | index = kvm_page_table_hashfn(gfn); | 2674 | index = kvm_page_table_hashfn(gfn); |
2661 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; | 2675 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; |
2676 | |||
2677 | restart: | ||
2662 | hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { | 2678 | hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { |
2663 | if (sp->gfn != gfn || sp->role.direct || sp->role.invalid) | 2679 | if (sp->gfn != gfn || sp->role.direct || sp->role.invalid) |
2664 | continue; | 2680 | continue; |
2665 | pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8; | 2681 | pte_size = sp->role.cr4_pae ? 8 : 4; |
2666 | misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1); | 2682 | misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1); |
2667 | misaligned |= bytes < 4; | 2683 | misaligned |= bytes < 4; |
2668 | if (misaligned || flooded) { | 2684 | if (misaligned || flooded) { |
@@ -2679,14 +2695,14 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
2679 | pgprintk("misaligned: gpa %llx bytes %d role %x\n", | 2695 | pgprintk("misaligned: gpa %llx bytes %d role %x\n", |
2680 | gpa, bytes, sp->role.word); | 2696 | gpa, bytes, sp->role.word); |
2681 | if (kvm_mmu_zap_page(vcpu->kvm, sp)) | 2697 | if (kvm_mmu_zap_page(vcpu->kvm, sp)) |
2682 | n = bucket->first; | 2698 | goto restart; |
2683 | ++vcpu->kvm->stat.mmu_flooded; | 2699 | ++vcpu->kvm->stat.mmu_flooded; |
2684 | continue; | 2700 | continue; |
2685 | } | 2701 | } |
2686 | page_offset = offset; | 2702 | page_offset = offset; |
2687 | level = sp->role.level; | 2703 | level = sp->role.level; |
2688 | npte = 1; | 2704 | npte = 1; |
2689 | if (sp->role.glevels == PT32_ROOT_LEVEL) { | 2705 | if (!sp->role.cr4_pae) { |
2690 | page_offset <<= 1; /* 32->64 */ | 2706 | page_offset <<= 1; /* 32->64 */ |
2691 | /* | 2707 | /* |
2692 | * A 32-bit pde maps 4MB while the shadow pdes map | 2708 | * A 32-bit pde maps 4MB while the shadow pdes map |
@@ -2704,20 +2720,11 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
2704 | continue; | 2720 | continue; |
2705 | } | 2721 | } |
2706 | spte = &sp->spt[page_offset / sizeof(*spte)]; | 2722 | spte = &sp->spt[page_offset / sizeof(*spte)]; |
2707 | if ((gpa & (pte_size - 1)) || (bytes < pte_size)) { | ||
2708 | gentry = 0; | ||
2709 | r = kvm_read_guest_atomic(vcpu->kvm, | ||
2710 | gpa & ~(u64)(pte_size - 1), | ||
2711 | &gentry, pte_size); | ||
2712 | new = (const void *)&gentry; | ||
2713 | if (r < 0) | ||
2714 | new = NULL; | ||
2715 | } | ||
2716 | while (npte--) { | 2723 | while (npte--) { |
2717 | entry = *spte; | 2724 | entry = *spte; |
2718 | mmu_pte_write_zap_pte(vcpu, sp, spte); | 2725 | mmu_pte_write_zap_pte(vcpu, sp, spte); |
2719 | if (new) | 2726 | if (gentry) |
2720 | mmu_pte_write_new_pte(vcpu, sp, spte, new); | 2727 | mmu_pte_write_new_pte(vcpu, sp, spte, &gentry); |
2721 | mmu_pte_write_flush_tlb(vcpu, entry, *spte); | 2728 | mmu_pte_write_flush_tlb(vcpu, entry, *spte); |
2722 | ++spte; | 2729 | ++spte; |
2723 | } | 2730 | } |
@@ -2897,10 +2904,11 @@ void kvm_mmu_zap_all(struct kvm *kvm) | |||
2897 | struct kvm_mmu_page *sp, *node; | 2904 | struct kvm_mmu_page *sp, *node; |
2898 | 2905 | ||
2899 | spin_lock(&kvm->mmu_lock); | 2906 | spin_lock(&kvm->mmu_lock); |
2907 | restart: | ||
2900 | list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link) | 2908 | list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link) |
2901 | if (kvm_mmu_zap_page(kvm, sp)) | 2909 | if (kvm_mmu_zap_page(kvm, sp)) |
2902 | node = container_of(kvm->arch.active_mmu_pages.next, | 2910 | goto restart; |
2903 | struct kvm_mmu_page, link); | 2911 | |
2904 | spin_unlock(&kvm->mmu_lock); | 2912 | spin_unlock(&kvm->mmu_lock); |
2905 | 2913 | ||
2906 | kvm_flush_remote_tlbs(kvm); | 2914 | kvm_flush_remote_tlbs(kvm); |
@@ -3171,8 +3179,7 @@ static gva_t canonicalize(gva_t gva) | |||
3171 | } | 3179 | } |
3172 | 3180 | ||
3173 | 3181 | ||
3174 | typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp, | 3182 | typedef void (*inspect_spte_fn) (struct kvm *kvm, u64 *sptep); |
3175 | u64 *sptep); | ||
3176 | 3183 | ||
3177 | static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, | 3184 | static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, |
3178 | inspect_spte_fn fn) | 3185 | inspect_spte_fn fn) |
@@ -3188,7 +3195,7 @@ static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, | |||
3188 | child = page_header(ent & PT64_BASE_ADDR_MASK); | 3195 | child = page_header(ent & PT64_BASE_ADDR_MASK); |
3189 | __mmu_spte_walk(kvm, child, fn); | 3196 | __mmu_spte_walk(kvm, child, fn); |
3190 | } else | 3197 | } else |
3191 | fn(kvm, sp, &sp->spt[i]); | 3198 | fn(kvm, &sp->spt[i]); |
3192 | } | 3199 | } |
3193 | } | 3200 | } |
3194 | } | 3201 | } |
@@ -3279,6 +3286,8 @@ static void audit_mappings(struct kvm_vcpu *vcpu) | |||
3279 | 3286 | ||
3280 | static int count_rmaps(struct kvm_vcpu *vcpu) | 3287 | static int count_rmaps(struct kvm_vcpu *vcpu) |
3281 | { | 3288 | { |
3289 | struct kvm *kvm = vcpu->kvm; | ||
3290 | struct kvm_memslots *slots; | ||
3282 | int nmaps = 0; | 3291 | int nmaps = 0; |
3283 | int i, j, k, idx; | 3292 | int i, j, k, idx; |
3284 | 3293 | ||
@@ -3312,7 +3321,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu) | |||
3312 | return nmaps; | 3321 | return nmaps; |
3313 | } | 3322 | } |
3314 | 3323 | ||
3315 | void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep) | 3324 | void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) |
3316 | { | 3325 | { |
3317 | unsigned long *rmapp; | 3326 | unsigned long *rmapp; |
3318 | struct kvm_mmu_page *rev_sp; | 3327 | struct kvm_mmu_page *rev_sp; |
@@ -3328,14 +3337,14 @@ void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep) | |||
3328 | printk(KERN_ERR "%s: no memslot for gfn %ld\n", | 3337 | printk(KERN_ERR "%s: no memslot for gfn %ld\n", |
3329 | audit_msg, gfn); | 3338 | audit_msg, gfn); |
3330 | printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n", | 3339 | printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n", |
3331 | audit_msg, sptep - rev_sp->spt, | 3340 | audit_msg, (long int)(sptep - rev_sp->spt), |
3332 | rev_sp->gfn); | 3341 | rev_sp->gfn); |
3333 | dump_stack(); | 3342 | dump_stack(); |
3334 | return; | 3343 | return; |
3335 | } | 3344 | } |
3336 | 3345 | ||
3337 | rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt], | 3346 | rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt], |
3338 | is_large_pte(*sptep)); | 3347 | rev_sp->role.level); |
3339 | if (!*rmapp) { | 3348 | if (!*rmapp) { |
3340 | if (!printk_ratelimit()) | 3349 | if (!printk_ratelimit()) |
3341 | return; | 3350 | return; |
@@ -3370,7 +3379,7 @@ static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu) | |||
3370 | continue; | 3379 | continue; |
3371 | if (!(ent & PT_WRITABLE_MASK)) | 3380 | if (!(ent & PT_WRITABLE_MASK)) |
3372 | continue; | 3381 | continue; |
3373 | inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]); | 3382 | inspect_spte_has_rmap(vcpu->kvm, &pt[i]); |
3374 | } | 3383 | } |
3375 | } | 3384 | } |
3376 | return; | 3385 | return; |
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h index 3e4a5c6ca2a9..3851f1f3030c 100644 --- a/arch/x86/kvm/mmutrace.h +++ b/arch/x86/kvm/mmutrace.h | |||
@@ -6,8 +6,6 @@ | |||
6 | 6 | ||
7 | #undef TRACE_SYSTEM | 7 | #undef TRACE_SYSTEM |
8 | #define TRACE_SYSTEM kvmmmu | 8 | #define TRACE_SYSTEM kvmmmu |
9 | #define TRACE_INCLUDE_PATH . | ||
10 | #define TRACE_INCLUDE_FILE mmutrace | ||
11 | 9 | ||
12 | #define KVM_MMU_PAGE_FIELDS \ | 10 | #define KVM_MMU_PAGE_FIELDS \ |
13 | __field(__u64, gfn) \ | 11 | __field(__u64, gfn) \ |
@@ -30,9 +28,10 @@ | |||
30 | \ | 28 | \ |
31 | role.word = __entry->role; \ | 29 | role.word = __entry->role; \ |
32 | \ | 30 | \ |
33 | trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge" \ | 31 | trace_seq_printf(p, "sp gfn %llx %u%s q%u%s %s%s %spge" \ |
34 | " %snxe root %u %s%c", \ | 32 | " %snxe root %u %s%c", \ |
35 | __entry->gfn, role.level, role.glevels, \ | 33 | __entry->gfn, role.level, \ |
34 | role.cr4_pae ? " pae" : "", \ | ||
36 | role.quadrant, \ | 35 | role.quadrant, \ |
37 | role.direct ? " direct" : "", \ | 36 | role.direct ? " direct" : "", \ |
38 | access_str[role.access], \ | 37 | access_str[role.access], \ |
@@ -216,5 +215,10 @@ TRACE_EVENT( | |||
216 | 215 | ||
217 | #endif /* _TRACE_KVMMMU_H */ | 216 | #endif /* _TRACE_KVMMMU_H */ |
218 | 217 | ||
218 | #undef TRACE_INCLUDE_PATH | ||
219 | #define TRACE_INCLUDE_PATH . | ||
220 | #undef TRACE_INCLUDE_FILE | ||
221 | #define TRACE_INCLUDE_FILE mmutrace | ||
222 | |||
219 | /* This part must be outside protection */ | 223 | /* This part must be outside protection */ |
220 | #include <trace/define_trace.h> | 224 | #include <trace/define_trace.h> |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 81eab9a50e6a..d9dea288e51d 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -170,7 +170,7 @@ walk: | |||
170 | goto access_error; | 170 | goto access_error; |
171 | 171 | ||
172 | #if PTTYPE == 64 | 172 | #if PTTYPE == 64 |
173 | if (fetch_fault && is_nx(vcpu) && (pte & PT64_NX_MASK)) | 173 | if (fetch_fault && (pte & PT64_NX_MASK)) |
174 | goto access_error; | 174 | goto access_error; |
175 | #endif | 175 | #endif |
176 | 176 | ||
@@ -258,11 +258,17 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, | |||
258 | pt_element_t gpte; | 258 | pt_element_t gpte; |
259 | unsigned pte_access; | 259 | unsigned pte_access; |
260 | pfn_t pfn; | 260 | pfn_t pfn; |
261 | u64 new_spte; | ||
261 | 262 | ||
262 | gpte = *(const pt_element_t *)pte; | 263 | gpte = *(const pt_element_t *)pte; |
263 | if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { | 264 | if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { |
264 | if (!is_present_gpte(gpte)) | 265 | if (!is_present_gpte(gpte)) { |
265 | __set_spte(spte, shadow_notrap_nonpresent_pte); | 266 | if (page->unsync) |
267 | new_spte = shadow_trap_nonpresent_pte; | ||
268 | else | ||
269 | new_spte = shadow_notrap_nonpresent_pte; | ||
270 | __set_spte(spte, new_spte); | ||
271 | } | ||
266 | return; | 272 | return; |
267 | } | 273 | } |
268 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); | 274 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); |
@@ -457,6 +463,7 @@ out_unlock: | |||
457 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | 463 | static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) |
458 | { | 464 | { |
459 | struct kvm_shadow_walk_iterator iterator; | 465 | struct kvm_shadow_walk_iterator iterator; |
466 | gpa_t pte_gpa = -1; | ||
460 | int level; | 467 | int level; |
461 | u64 *sptep; | 468 | u64 *sptep; |
462 | int need_flush = 0; | 469 | int need_flush = 0; |
@@ -470,6 +477,10 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
470 | if (level == PT_PAGE_TABLE_LEVEL || | 477 | if (level == PT_PAGE_TABLE_LEVEL || |
471 | ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || | 478 | ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || |
472 | ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { | 479 | ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { |
480 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); | ||
481 | |||
482 | pte_gpa = (sp->gfn << PAGE_SHIFT); | ||
483 | pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); | ||
473 | 484 | ||
474 | if (is_shadow_present_pte(*sptep)) { | 485 | if (is_shadow_present_pte(*sptep)) { |
475 | rmap_remove(vcpu->kvm, sptep); | 486 | rmap_remove(vcpu->kvm, sptep); |
@@ -487,7 +498,17 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
487 | 498 | ||
488 | if (need_flush) | 499 | if (need_flush) |
489 | kvm_flush_remote_tlbs(vcpu->kvm); | 500 | kvm_flush_remote_tlbs(vcpu->kvm); |
501 | |||
502 | atomic_inc(&vcpu->kvm->arch.invlpg_counter); | ||
503 | |||
490 | spin_unlock(&vcpu->kvm->mmu_lock); | 504 | spin_unlock(&vcpu->kvm->mmu_lock); |
505 | |||
506 | if (pte_gpa == -1) | ||
507 | return; | ||
508 | |||
509 | if (mmu_topup_memory_caches(vcpu)) | ||
510 | return; | ||
511 | kvm_mmu_pte_write(vcpu, pte_gpa, NULL, sizeof(pt_element_t), 0); | ||
491 | } | 512 | } |
492 | 513 | ||
493 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, | 514 | static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 445c59411ed0..ab78eb8ba899 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -44,10 +44,11 @@ MODULE_LICENSE("GPL"); | |||
44 | #define SEG_TYPE_LDT 2 | 44 | #define SEG_TYPE_LDT 2 |
45 | #define SEG_TYPE_BUSY_TSS16 3 | 45 | #define SEG_TYPE_BUSY_TSS16 3 |
46 | 46 | ||
47 | #define SVM_FEATURE_NPT (1 << 0) | 47 | #define SVM_FEATURE_NPT (1 << 0) |
48 | #define SVM_FEATURE_LBRV (1 << 1) | 48 | #define SVM_FEATURE_LBRV (1 << 1) |
49 | #define SVM_FEATURE_SVML (1 << 2) | 49 | #define SVM_FEATURE_SVML (1 << 2) |
50 | #define SVM_FEATURE_PAUSE_FILTER (1 << 10) | 50 | #define SVM_FEATURE_NRIP (1 << 3) |
51 | #define SVM_FEATURE_PAUSE_FILTER (1 << 10) | ||
51 | 52 | ||
52 | #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ | 53 | #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ |
53 | #define NESTED_EXIT_DONE 1 /* Exit caused nested vmexit */ | 54 | #define NESTED_EXIT_DONE 1 /* Exit caused nested vmexit */ |
@@ -70,6 +71,7 @@ struct kvm_vcpu; | |||
70 | struct nested_state { | 71 | struct nested_state { |
71 | struct vmcb *hsave; | 72 | struct vmcb *hsave; |
72 | u64 hsave_msr; | 73 | u64 hsave_msr; |
74 | u64 vm_cr_msr; | ||
73 | u64 vmcb; | 75 | u64 vmcb; |
74 | 76 | ||
75 | /* These are the merged vectors */ | 77 | /* These are the merged vectors */ |
@@ -77,6 +79,7 @@ struct nested_state { | |||
77 | 79 | ||
78 | /* gpa pointers to the real vectors */ | 80 | /* gpa pointers to the real vectors */ |
79 | u64 vmcb_msrpm; | 81 | u64 vmcb_msrpm; |
82 | u64 vmcb_iopm; | ||
80 | 83 | ||
81 | /* A VMEXIT is required but not yet emulated */ | 84 | /* A VMEXIT is required but not yet emulated */ |
82 | bool exit_required; | 85 | bool exit_required; |
@@ -91,6 +94,9 @@ struct nested_state { | |||
91 | 94 | ||
92 | }; | 95 | }; |
93 | 96 | ||
97 | #define MSRPM_OFFSETS 16 | ||
98 | static u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; | ||
99 | |||
94 | struct vcpu_svm { | 100 | struct vcpu_svm { |
95 | struct kvm_vcpu vcpu; | 101 | struct kvm_vcpu vcpu; |
96 | struct vmcb *vmcb; | 102 | struct vmcb *vmcb; |
@@ -110,13 +116,39 @@ struct vcpu_svm { | |||
110 | struct nested_state nested; | 116 | struct nested_state nested; |
111 | 117 | ||
112 | bool nmi_singlestep; | 118 | bool nmi_singlestep; |
119 | |||
120 | unsigned int3_injected; | ||
121 | unsigned long int3_rip; | ||
122 | }; | ||
123 | |||
124 | #define MSR_INVALID 0xffffffffU | ||
125 | |||
126 | static struct svm_direct_access_msrs { | ||
127 | u32 index; /* Index of the MSR */ | ||
128 | bool always; /* True if intercept is always on */ | ||
129 | } direct_access_msrs[] = { | ||
130 | { .index = MSR_K6_STAR, .always = true }, | ||
131 | { .index = MSR_IA32_SYSENTER_CS, .always = true }, | ||
132 | #ifdef CONFIG_X86_64 | ||
133 | { .index = MSR_GS_BASE, .always = true }, | ||
134 | { .index = MSR_FS_BASE, .always = true }, | ||
135 | { .index = MSR_KERNEL_GS_BASE, .always = true }, | ||
136 | { .index = MSR_LSTAR, .always = true }, | ||
137 | { .index = MSR_CSTAR, .always = true }, | ||
138 | { .index = MSR_SYSCALL_MASK, .always = true }, | ||
139 | #endif | ||
140 | { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false }, | ||
141 | { .index = MSR_IA32_LASTBRANCHTOIP, .always = false }, | ||
142 | { .index = MSR_IA32_LASTINTFROMIP, .always = false }, | ||
143 | { .index = MSR_IA32_LASTINTTOIP, .always = false }, | ||
144 | { .index = MSR_INVALID, .always = false }, | ||
113 | }; | 145 | }; |
114 | 146 | ||
115 | /* enable NPT for AMD64 and X86 with PAE */ | 147 | /* enable NPT for AMD64 and X86 with PAE */ |
116 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | 148 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) |
117 | static bool npt_enabled = true; | 149 | static bool npt_enabled = true; |
118 | #else | 150 | #else |
119 | static bool npt_enabled = false; | 151 | static bool npt_enabled; |
120 | #endif | 152 | #endif |
121 | static int npt = 1; | 153 | static int npt = 1; |
122 | 154 | ||
@@ -129,6 +161,7 @@ static void svm_flush_tlb(struct kvm_vcpu *vcpu); | |||
129 | static void svm_complete_interrupts(struct vcpu_svm *svm); | 161 | static void svm_complete_interrupts(struct vcpu_svm *svm); |
130 | 162 | ||
131 | static int nested_svm_exit_handled(struct vcpu_svm *svm); | 163 | static int nested_svm_exit_handled(struct vcpu_svm *svm); |
164 | static int nested_svm_intercept(struct vcpu_svm *svm); | ||
132 | static int nested_svm_vmexit(struct vcpu_svm *svm); | 165 | static int nested_svm_vmexit(struct vcpu_svm *svm); |
133 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 166 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
134 | bool has_error_code, u32 error_code); | 167 | bool has_error_code, u32 error_code); |
@@ -163,8 +196,8 @@ static unsigned long iopm_base; | |||
163 | struct kvm_ldttss_desc { | 196 | struct kvm_ldttss_desc { |
164 | u16 limit0; | 197 | u16 limit0; |
165 | u16 base0; | 198 | u16 base0; |
166 | unsigned base1 : 8, type : 5, dpl : 2, p : 1; | 199 | unsigned base1:8, type:5, dpl:2, p:1; |
167 | unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; | 200 | unsigned limit1:4, zero0:3, g:1, base2:8; |
168 | u32 base3; | 201 | u32 base3; |
169 | u32 zero1; | 202 | u32 zero1; |
170 | } __attribute__((packed)); | 203 | } __attribute__((packed)); |
@@ -194,6 +227,27 @@ static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000}; | |||
194 | #define MSRS_RANGE_SIZE 2048 | 227 | #define MSRS_RANGE_SIZE 2048 |
195 | #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2) | 228 | #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2) |
196 | 229 | ||
230 | static u32 svm_msrpm_offset(u32 msr) | ||
231 | { | ||
232 | u32 offset; | ||
233 | int i; | ||
234 | |||
235 | for (i = 0; i < NUM_MSR_MAPS; i++) { | ||
236 | if (msr < msrpm_ranges[i] || | ||
237 | msr >= msrpm_ranges[i] + MSRS_IN_RANGE) | ||
238 | continue; | ||
239 | |||
240 | offset = (msr - msrpm_ranges[i]) / 4; /* 4 msrs per u8 */ | ||
241 | offset += (i * MSRS_RANGE_SIZE); /* add range offset */ | ||
242 | |||
243 | /* Now we have the u8 offset - but need the u32 offset */ | ||
244 | return offset / 4; | ||
245 | } | ||
246 | |||
247 | /* MSR not in any range */ | ||
248 | return MSR_INVALID; | ||
249 | } | ||
250 | |||
197 | #define MAX_INST_SIZE 15 | 251 | #define MAX_INST_SIZE 15 |
198 | 252 | ||
199 | static inline u32 svm_has(u32 feat) | 253 | static inline u32 svm_has(u32 feat) |
@@ -213,7 +267,7 @@ static inline void stgi(void) | |||
213 | 267 | ||
214 | static inline void invlpga(unsigned long addr, u32 asid) | 268 | static inline void invlpga(unsigned long addr, u32 asid) |
215 | { | 269 | { |
216 | asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); | 270 | asm volatile (__ex(SVM_INVLPGA) : : "a"(addr), "c"(asid)); |
217 | } | 271 | } |
218 | 272 | ||
219 | static inline void force_new_asid(struct kvm_vcpu *vcpu) | 273 | static inline void force_new_asid(struct kvm_vcpu *vcpu) |
@@ -235,23 +289,6 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
235 | vcpu->arch.efer = efer; | 289 | vcpu->arch.efer = efer; |
236 | } | 290 | } |
237 | 291 | ||
238 | static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | ||
239 | bool has_error_code, u32 error_code) | ||
240 | { | ||
241 | struct vcpu_svm *svm = to_svm(vcpu); | ||
242 | |||
243 | /* If we are within a nested VM we'd better #VMEXIT and let the | ||
244 | guest handle the exception */ | ||
245 | if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) | ||
246 | return; | ||
247 | |||
248 | svm->vmcb->control.event_inj = nr | ||
249 | | SVM_EVTINJ_VALID | ||
250 | | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) | ||
251 | | SVM_EVTINJ_TYPE_EXEPT; | ||
252 | svm->vmcb->control.event_inj_err = error_code; | ||
253 | } | ||
254 | |||
255 | static int is_external_interrupt(u32 info) | 292 | static int is_external_interrupt(u32 info) |
256 | { | 293 | { |
257 | info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; | 294 | info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; |
@@ -264,7 +301,7 @@ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
264 | u32 ret = 0; | 301 | u32 ret = 0; |
265 | 302 | ||
266 | if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) | 303 | if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) |
267 | ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS; | 304 | ret |= KVM_X86_SHADOW_INT_STI | KVM_X86_SHADOW_INT_MOV_SS; |
268 | return ret & mask; | 305 | return ret & mask; |
269 | } | 306 | } |
270 | 307 | ||
@@ -283,6 +320,9 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | |||
283 | { | 320 | { |
284 | struct vcpu_svm *svm = to_svm(vcpu); | 321 | struct vcpu_svm *svm = to_svm(vcpu); |
285 | 322 | ||
323 | if (svm->vmcb->control.next_rip != 0) | ||
324 | svm->next_rip = svm->vmcb->control.next_rip; | ||
325 | |||
286 | if (!svm->next_rip) { | 326 | if (!svm->next_rip) { |
287 | if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != | 327 | if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != |
288 | EMULATE_DONE) | 328 | EMULATE_DONE) |
@@ -297,6 +337,41 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) | |||
297 | svm_set_interrupt_shadow(vcpu, 0); | 337 | svm_set_interrupt_shadow(vcpu, 0); |
298 | } | 338 | } |
299 | 339 | ||
340 | static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | ||
341 | bool has_error_code, u32 error_code) | ||
342 | { | ||
343 | struct vcpu_svm *svm = to_svm(vcpu); | ||
344 | |||
345 | /* | ||
346 | * If we are within a nested VM we'd better #VMEXIT and let the guest | ||
347 | * handle the exception | ||
348 | */ | ||
349 | if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) | ||
350 | return; | ||
351 | |||
352 | if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) { | ||
353 | unsigned long rip, old_rip = kvm_rip_read(&svm->vcpu); | ||
354 | |||
355 | /* | ||
356 | * For guest debugging where we have to reinject #BP if some | ||
357 | * INT3 is guest-owned: | ||
358 | * Emulate nRIP by moving RIP forward. Will fail if injection | ||
359 | * raises a fault that is not intercepted. Still better than | ||
360 | * failing in all cases. | ||
361 | */ | ||
362 | skip_emulated_instruction(&svm->vcpu); | ||
363 | rip = kvm_rip_read(&svm->vcpu); | ||
364 | svm->int3_rip = rip + svm->vmcb->save.cs.base; | ||
365 | svm->int3_injected = rip - old_rip; | ||
366 | } | ||
367 | |||
368 | svm->vmcb->control.event_inj = nr | ||
369 | | SVM_EVTINJ_VALID | ||
370 | | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) | ||
371 | | SVM_EVTINJ_TYPE_EXEPT; | ||
372 | svm->vmcb->control.event_inj_err = error_code; | ||
373 | } | ||
374 | |||
300 | static int has_svm(void) | 375 | static int has_svm(void) |
301 | { | 376 | { |
302 | const char *msg; | 377 | const char *msg; |
@@ -319,7 +394,7 @@ static int svm_hardware_enable(void *garbage) | |||
319 | 394 | ||
320 | struct svm_cpu_data *sd; | 395 | struct svm_cpu_data *sd; |
321 | uint64_t efer; | 396 | uint64_t efer; |
322 | struct descriptor_table gdt_descr; | 397 | struct desc_ptr gdt_descr; |
323 | struct desc_struct *gdt; | 398 | struct desc_struct *gdt; |
324 | int me = raw_smp_processor_id(); | 399 | int me = raw_smp_processor_id(); |
325 | 400 | ||
@@ -344,8 +419,8 @@ static int svm_hardware_enable(void *garbage) | |||
344 | sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; | 419 | sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; |
345 | sd->next_asid = sd->max_asid + 1; | 420 | sd->next_asid = sd->max_asid + 1; |
346 | 421 | ||
347 | kvm_get_gdt(&gdt_descr); | 422 | native_store_gdt(&gdt_descr); |
348 | gdt = (struct desc_struct *)gdt_descr.base; | 423 | gdt = (struct desc_struct *)gdt_descr.address; |
349 | sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); | 424 | sd->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); |
350 | 425 | ||
351 | wrmsrl(MSR_EFER, efer | EFER_SVME); | 426 | wrmsrl(MSR_EFER, efer | EFER_SVME); |
@@ -391,42 +466,98 @@ err_1: | |||
391 | 466 | ||
392 | } | 467 | } |
393 | 468 | ||
469 | static bool valid_msr_intercept(u32 index) | ||
470 | { | ||
471 | int i; | ||
472 | |||
473 | for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) | ||
474 | if (direct_access_msrs[i].index == index) | ||
475 | return true; | ||
476 | |||
477 | return false; | ||
478 | } | ||
479 | |||
394 | static void set_msr_interception(u32 *msrpm, unsigned msr, | 480 | static void set_msr_interception(u32 *msrpm, unsigned msr, |
395 | int read, int write) | 481 | int read, int write) |
396 | { | 482 | { |
483 | u8 bit_read, bit_write; | ||
484 | unsigned long tmp; | ||
485 | u32 offset; | ||
486 | |||
487 | /* | ||
488 | * If this warning triggers extend the direct_access_msrs list at the | ||
489 | * beginning of the file | ||
490 | */ | ||
491 | WARN_ON(!valid_msr_intercept(msr)); | ||
492 | |||
493 | offset = svm_msrpm_offset(msr); | ||
494 | bit_read = 2 * (msr & 0x0f); | ||
495 | bit_write = 2 * (msr & 0x0f) + 1; | ||
496 | tmp = msrpm[offset]; | ||
497 | |||
498 | BUG_ON(offset == MSR_INVALID); | ||
499 | |||
500 | read ? clear_bit(bit_read, &tmp) : set_bit(bit_read, &tmp); | ||
501 | write ? clear_bit(bit_write, &tmp) : set_bit(bit_write, &tmp); | ||
502 | |||
503 | msrpm[offset] = tmp; | ||
504 | } | ||
505 | |||
506 | static void svm_vcpu_init_msrpm(u32 *msrpm) | ||
507 | { | ||
397 | int i; | 508 | int i; |
398 | 509 | ||
399 | for (i = 0; i < NUM_MSR_MAPS; i++) { | 510 | memset(msrpm, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); |
400 | if (msr >= msrpm_ranges[i] && | 511 | |
401 | msr < msrpm_ranges[i] + MSRS_IN_RANGE) { | 512 | for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { |
402 | u32 msr_offset = (i * MSRS_IN_RANGE + msr - | 513 | if (!direct_access_msrs[i].always) |
403 | msrpm_ranges[i]) * 2; | 514 | continue; |
404 | 515 | ||
405 | u32 *base = msrpm + (msr_offset / 32); | 516 | set_msr_interception(msrpm, direct_access_msrs[i].index, 1, 1); |
406 | u32 msr_shift = msr_offset % 32; | 517 | } |
407 | u32 mask = ((write) ? 0 : 2) | ((read) ? 0 : 1); | 518 | } |
408 | *base = (*base & ~(0x3 << msr_shift)) | | 519 | |
409 | (mask << msr_shift); | 520 | static void add_msr_offset(u32 offset) |
521 | { | ||
522 | int i; | ||
523 | |||
524 | for (i = 0; i < MSRPM_OFFSETS; ++i) { | ||
525 | |||
526 | /* Offset already in list? */ | ||
527 | if (msrpm_offsets[i] == offset) | ||
410 | return; | 528 | return; |
411 | } | 529 | |
530 | /* Slot used by another offset? */ | ||
531 | if (msrpm_offsets[i] != MSR_INVALID) | ||
532 | continue; | ||
533 | |||
534 | /* Add offset to list */ | ||
535 | msrpm_offsets[i] = offset; | ||
536 | |||
537 | return; | ||
412 | } | 538 | } |
539 | |||
540 | /* | ||
541 | * If this BUG triggers the msrpm_offsets table has an overflow. Just | ||
542 | * increase MSRPM_OFFSETS in this case. | ||
543 | */ | ||
413 | BUG(); | 544 | BUG(); |
414 | } | 545 | } |
415 | 546 | ||
416 | static void svm_vcpu_init_msrpm(u32 *msrpm) | 547 | static void init_msrpm_offsets(void) |
417 | { | 548 | { |
418 | memset(msrpm, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER)); | 549 | int i; |
419 | 550 | ||
420 | #ifdef CONFIG_X86_64 | 551 | memset(msrpm_offsets, 0xff, sizeof(msrpm_offsets)); |
421 | set_msr_interception(msrpm, MSR_GS_BASE, 1, 1); | 552 | |
422 | set_msr_interception(msrpm, MSR_FS_BASE, 1, 1); | 553 | for (i = 0; direct_access_msrs[i].index != MSR_INVALID; i++) { |
423 | set_msr_interception(msrpm, MSR_KERNEL_GS_BASE, 1, 1); | 554 | u32 offset; |
424 | set_msr_interception(msrpm, MSR_LSTAR, 1, 1); | 555 | |
425 | set_msr_interception(msrpm, MSR_CSTAR, 1, 1); | 556 | offset = svm_msrpm_offset(direct_access_msrs[i].index); |
426 | set_msr_interception(msrpm, MSR_SYSCALL_MASK, 1, 1); | 557 | BUG_ON(offset == MSR_INVALID); |
427 | #endif | 558 | |
428 | set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); | 559 | add_msr_offset(offset); |
429 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); | 560 | } |
430 | } | 561 | } |
431 | 562 | ||
432 | static void svm_enable_lbrv(struct vcpu_svm *svm) | 563 | static void svm_enable_lbrv(struct vcpu_svm *svm) |
@@ -467,6 +598,8 @@ static __init int svm_hardware_setup(void) | |||
467 | memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER)); | 598 | memset(iopm_va, 0xff, PAGE_SIZE * (1 << IOPM_ALLOC_ORDER)); |
468 | iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT; | 599 | iopm_base = page_to_pfn(iopm_pages) << PAGE_SHIFT; |
469 | 600 | ||
601 | init_msrpm_offsets(); | ||
602 | |||
470 | if (boot_cpu_has(X86_FEATURE_NX)) | 603 | if (boot_cpu_has(X86_FEATURE_NX)) |
471 | kvm_enable_efer_bits(EFER_NX); | 604 | kvm_enable_efer_bits(EFER_NX); |
472 | 605 | ||
@@ -523,7 +656,7 @@ static void init_seg(struct vmcb_seg *seg) | |||
523 | { | 656 | { |
524 | seg->selector = 0; | 657 | seg->selector = 0; |
525 | seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK | | 658 | seg->attrib = SVM_SELECTOR_P_MASK | SVM_SELECTOR_S_MASK | |
526 | SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */ | 659 | SVM_SELECTOR_WRITE_MASK; /* Read/Write Data Segment */ |
527 | seg->limit = 0xffff; | 660 | seg->limit = 0xffff; |
528 | seg->base = 0; | 661 | seg->base = 0; |
529 | } | 662 | } |
@@ -543,16 +676,16 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
543 | 676 | ||
544 | svm->vcpu.fpu_active = 1; | 677 | svm->vcpu.fpu_active = 1; |
545 | 678 | ||
546 | control->intercept_cr_read = INTERCEPT_CR0_MASK | | 679 | control->intercept_cr_read = INTERCEPT_CR0_MASK | |
547 | INTERCEPT_CR3_MASK | | 680 | INTERCEPT_CR3_MASK | |
548 | INTERCEPT_CR4_MASK; | 681 | INTERCEPT_CR4_MASK; |
549 | 682 | ||
550 | control->intercept_cr_write = INTERCEPT_CR0_MASK | | 683 | control->intercept_cr_write = INTERCEPT_CR0_MASK | |
551 | INTERCEPT_CR3_MASK | | 684 | INTERCEPT_CR3_MASK | |
552 | INTERCEPT_CR4_MASK | | 685 | INTERCEPT_CR4_MASK | |
553 | INTERCEPT_CR8_MASK; | 686 | INTERCEPT_CR8_MASK; |
554 | 687 | ||
555 | control->intercept_dr_read = INTERCEPT_DR0_MASK | | 688 | control->intercept_dr_read = INTERCEPT_DR0_MASK | |
556 | INTERCEPT_DR1_MASK | | 689 | INTERCEPT_DR1_MASK | |
557 | INTERCEPT_DR2_MASK | | 690 | INTERCEPT_DR2_MASK | |
558 | INTERCEPT_DR3_MASK | | 691 | INTERCEPT_DR3_MASK | |
@@ -561,7 +694,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
561 | INTERCEPT_DR6_MASK | | 694 | INTERCEPT_DR6_MASK | |
562 | INTERCEPT_DR7_MASK; | 695 | INTERCEPT_DR7_MASK; |
563 | 696 | ||
564 | control->intercept_dr_write = INTERCEPT_DR0_MASK | | 697 | control->intercept_dr_write = INTERCEPT_DR0_MASK | |
565 | INTERCEPT_DR1_MASK | | 698 | INTERCEPT_DR1_MASK | |
566 | INTERCEPT_DR2_MASK | | 699 | INTERCEPT_DR2_MASK | |
567 | INTERCEPT_DR3_MASK | | 700 | INTERCEPT_DR3_MASK | |
@@ -575,7 +708,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
575 | (1 << MC_VECTOR); | 708 | (1 << MC_VECTOR); |
576 | 709 | ||
577 | 710 | ||
578 | control->intercept = (1ULL << INTERCEPT_INTR) | | 711 | control->intercept = (1ULL << INTERCEPT_INTR) | |
579 | (1ULL << INTERCEPT_NMI) | | 712 | (1ULL << INTERCEPT_NMI) | |
580 | (1ULL << INTERCEPT_SMI) | | 713 | (1ULL << INTERCEPT_SMI) | |
581 | (1ULL << INTERCEPT_SELECTIVE_CR0) | | 714 | (1ULL << INTERCEPT_SELECTIVE_CR0) | |
@@ -636,7 +769,8 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
636 | save->rip = 0x0000fff0; | 769 | save->rip = 0x0000fff0; |
637 | svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; | 770 | svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip; |
638 | 771 | ||
639 | /* This is the guest-visible cr0 value. | 772 | /* |
773 | * This is the guest-visible cr0 value. | ||
640 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. | 774 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. |
641 | */ | 775 | */ |
642 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; | 776 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; |
@@ -706,30 +840,30 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
706 | if (err) | 840 | if (err) |
707 | goto free_svm; | 841 | goto free_svm; |
708 | 842 | ||
843 | err = -ENOMEM; | ||
709 | page = alloc_page(GFP_KERNEL); | 844 | page = alloc_page(GFP_KERNEL); |
710 | if (!page) { | 845 | if (!page) |
711 | err = -ENOMEM; | ||
712 | goto uninit; | 846 | goto uninit; |
713 | } | ||
714 | 847 | ||
715 | err = -ENOMEM; | ||
716 | msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); | 848 | msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
717 | if (!msrpm_pages) | 849 | if (!msrpm_pages) |
718 | goto uninit; | 850 | goto free_page1; |
719 | 851 | ||
720 | nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); | 852 | nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); |
721 | if (!nested_msrpm_pages) | 853 | if (!nested_msrpm_pages) |
722 | goto uninit; | 854 | goto free_page2; |
723 | |||
724 | svm->msrpm = page_address(msrpm_pages); | ||
725 | svm_vcpu_init_msrpm(svm->msrpm); | ||
726 | 855 | ||
727 | hsave_page = alloc_page(GFP_KERNEL); | 856 | hsave_page = alloc_page(GFP_KERNEL); |
728 | if (!hsave_page) | 857 | if (!hsave_page) |
729 | goto uninit; | 858 | goto free_page3; |
859 | |||
730 | svm->nested.hsave = page_address(hsave_page); | 860 | svm->nested.hsave = page_address(hsave_page); |
731 | 861 | ||
862 | svm->msrpm = page_address(msrpm_pages); | ||
863 | svm_vcpu_init_msrpm(svm->msrpm); | ||
864 | |||
732 | svm->nested.msrpm = page_address(nested_msrpm_pages); | 865 | svm->nested.msrpm = page_address(nested_msrpm_pages); |
866 | svm_vcpu_init_msrpm(svm->nested.msrpm); | ||
733 | 867 | ||
734 | svm->vmcb = page_address(page); | 868 | svm->vmcb = page_address(page); |
735 | clear_page(svm->vmcb); | 869 | clear_page(svm->vmcb); |
@@ -744,6 +878,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
744 | 878 | ||
745 | return &svm->vcpu; | 879 | return &svm->vcpu; |
746 | 880 | ||
881 | free_page3: | ||
882 | __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); | ||
883 | free_page2: | ||
884 | __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); | ||
885 | free_page1: | ||
886 | __free_page(page); | ||
747 | uninit: | 887 | uninit: |
748 | kvm_vcpu_uninit(&svm->vcpu); | 888 | kvm_vcpu_uninit(&svm->vcpu); |
749 | free_svm: | 889 | free_svm: |
@@ -877,7 +1017,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, | |||
877 | var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1; | 1017 | var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1; |
878 | var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1; | 1018 | var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1; |
879 | 1019 | ||
880 | /* AMD's VMCB does not have an explicit unusable field, so emulate it | 1020 | /* |
1021 | * AMD's VMCB does not have an explicit unusable field, so emulate it | ||
881 | * for cross vendor migration purposes by "not present" | 1022 | * for cross vendor migration purposes by "not present" |
882 | */ | 1023 | */ |
883 | var->unusable = !var->present || (var->type == 0); | 1024 | var->unusable = !var->present || (var->type == 0); |
@@ -913,7 +1054,8 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, | |||
913 | var->type |= 0x1; | 1054 | var->type |= 0x1; |
914 | break; | 1055 | break; |
915 | case VCPU_SREG_SS: | 1056 | case VCPU_SREG_SS: |
916 | /* On AMD CPUs sometimes the DB bit in the segment | 1057 | /* |
1058 | * On AMD CPUs sometimes the DB bit in the segment | ||
917 | * descriptor is left as 1, although the whole segment has | 1059 | * descriptor is left as 1, although the whole segment has |
918 | * been made unusable. Clear it here to pass an Intel VMX | 1060 | * been made unusable. Clear it here to pass an Intel VMX |
919 | * entry check when cross vendor migrating. | 1061 | * entry check when cross vendor migrating. |
@@ -931,36 +1073,36 @@ static int svm_get_cpl(struct kvm_vcpu *vcpu) | |||
931 | return save->cpl; | 1073 | return save->cpl; |
932 | } | 1074 | } |
933 | 1075 | ||
934 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1076 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
935 | { | 1077 | { |
936 | struct vcpu_svm *svm = to_svm(vcpu); | 1078 | struct vcpu_svm *svm = to_svm(vcpu); |
937 | 1079 | ||
938 | dt->limit = svm->vmcb->save.idtr.limit; | 1080 | dt->size = svm->vmcb->save.idtr.limit; |
939 | dt->base = svm->vmcb->save.idtr.base; | 1081 | dt->address = svm->vmcb->save.idtr.base; |
940 | } | 1082 | } |
941 | 1083 | ||
942 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1084 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
943 | { | 1085 | { |
944 | struct vcpu_svm *svm = to_svm(vcpu); | 1086 | struct vcpu_svm *svm = to_svm(vcpu); |
945 | 1087 | ||
946 | svm->vmcb->save.idtr.limit = dt->limit; | 1088 | svm->vmcb->save.idtr.limit = dt->size; |
947 | svm->vmcb->save.idtr.base = dt->base ; | 1089 | svm->vmcb->save.idtr.base = dt->address ; |
948 | } | 1090 | } |
949 | 1091 | ||
950 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1092 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
951 | { | 1093 | { |
952 | struct vcpu_svm *svm = to_svm(vcpu); | 1094 | struct vcpu_svm *svm = to_svm(vcpu); |
953 | 1095 | ||
954 | dt->limit = svm->vmcb->save.gdtr.limit; | 1096 | dt->size = svm->vmcb->save.gdtr.limit; |
955 | dt->base = svm->vmcb->save.gdtr.base; | 1097 | dt->address = svm->vmcb->save.gdtr.base; |
956 | } | 1098 | } |
957 | 1099 | ||
958 | static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1100 | static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
959 | { | 1101 | { |
960 | struct vcpu_svm *svm = to_svm(vcpu); | 1102 | struct vcpu_svm *svm = to_svm(vcpu); |
961 | 1103 | ||
962 | svm->vmcb->save.gdtr.limit = dt->limit; | 1104 | svm->vmcb->save.gdtr.limit = dt->size; |
963 | svm->vmcb->save.gdtr.base = dt->base ; | 1105 | svm->vmcb->save.gdtr.base = dt->address ; |
964 | } | 1106 | } |
965 | 1107 | ||
966 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | 1108 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) |
@@ -973,6 +1115,7 @@ static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | |||
973 | 1115 | ||
974 | static void update_cr0_intercept(struct vcpu_svm *svm) | 1116 | static void update_cr0_intercept(struct vcpu_svm *svm) |
975 | { | 1117 | { |
1118 | struct vmcb *vmcb = svm->vmcb; | ||
976 | ulong gcr0 = svm->vcpu.arch.cr0; | 1119 | ulong gcr0 = svm->vcpu.arch.cr0; |
977 | u64 *hcr0 = &svm->vmcb->save.cr0; | 1120 | u64 *hcr0 = &svm->vmcb->save.cr0; |
978 | 1121 | ||
@@ -984,11 +1127,25 @@ static void update_cr0_intercept(struct vcpu_svm *svm) | |||
984 | 1127 | ||
985 | 1128 | ||
986 | if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { | 1129 | if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { |
987 | svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; | 1130 | vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; |
988 | svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; | 1131 | vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; |
1132 | if (is_nested(svm)) { | ||
1133 | struct vmcb *hsave = svm->nested.hsave; | ||
1134 | |||
1135 | hsave->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; | ||
1136 | hsave->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; | ||
1137 | vmcb->control.intercept_cr_read |= svm->nested.intercept_cr_read; | ||
1138 | vmcb->control.intercept_cr_write |= svm->nested.intercept_cr_write; | ||
1139 | } | ||
989 | } else { | 1140 | } else { |
990 | svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK; | 1141 | svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK; |
991 | svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK; | 1142 | svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK; |
1143 | if (is_nested(svm)) { | ||
1144 | struct vmcb *hsave = svm->nested.hsave; | ||
1145 | |||
1146 | hsave->control.intercept_cr_read |= INTERCEPT_CR0_MASK; | ||
1147 | hsave->control.intercept_cr_write |= INTERCEPT_CR0_MASK; | ||
1148 | } | ||
992 | } | 1149 | } |
993 | } | 1150 | } |
994 | 1151 | ||
@@ -996,6 +1153,27 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
996 | { | 1153 | { |
997 | struct vcpu_svm *svm = to_svm(vcpu); | 1154 | struct vcpu_svm *svm = to_svm(vcpu); |
998 | 1155 | ||
1156 | if (is_nested(svm)) { | ||
1157 | /* | ||
1158 | * We are here because we run in nested mode, the host kvm | ||
1159 | * intercepts cr0 writes but the l1 hypervisor does not. | ||
1160 | * But the L1 hypervisor may intercept selective cr0 writes. | ||
1161 | * This needs to be checked here. | ||
1162 | */ | ||
1163 | unsigned long old, new; | ||
1164 | |||
1165 | /* Remove bits that would trigger a real cr0 write intercept */ | ||
1166 | old = vcpu->arch.cr0 & SVM_CR0_SELECTIVE_MASK; | ||
1167 | new = cr0 & SVM_CR0_SELECTIVE_MASK; | ||
1168 | |||
1169 | if (old == new) { | ||
1170 | /* cr0 write with ts and mp unchanged */ | ||
1171 | svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE; | ||
1172 | if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) | ||
1173 | return; | ||
1174 | } | ||
1175 | } | ||
1176 | |||
999 | #ifdef CONFIG_X86_64 | 1177 | #ifdef CONFIG_X86_64 |
1000 | if (vcpu->arch.efer & EFER_LME) { | 1178 | if (vcpu->arch.efer & EFER_LME) { |
1001 | if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { | 1179 | if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { |
@@ -1129,70 +1307,11 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) | |||
1129 | svm->vmcb->control.asid = sd->next_asid++; | 1307 | svm->vmcb->control.asid = sd->next_asid++; |
1130 | } | 1308 | } |
1131 | 1309 | ||
1132 | static int svm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *dest) | 1310 | static void svm_set_dr7(struct kvm_vcpu *vcpu, unsigned long value) |
1133 | { | ||
1134 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1135 | |||
1136 | switch (dr) { | ||
1137 | case 0 ... 3: | ||
1138 | *dest = vcpu->arch.db[dr]; | ||
1139 | break; | ||
1140 | case 4: | ||
1141 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1142 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1143 | /* fall through */ | ||
1144 | case 6: | ||
1145 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | ||
1146 | *dest = vcpu->arch.dr6; | ||
1147 | else | ||
1148 | *dest = svm->vmcb->save.dr6; | ||
1149 | break; | ||
1150 | case 5: | ||
1151 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1152 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1153 | /* fall through */ | ||
1154 | case 7: | ||
1155 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | ||
1156 | *dest = vcpu->arch.dr7; | ||
1157 | else | ||
1158 | *dest = svm->vmcb->save.dr7; | ||
1159 | break; | ||
1160 | } | ||
1161 | |||
1162 | return EMULATE_DONE; | ||
1163 | } | ||
1164 | |||
1165 | static int svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value) | ||
1166 | { | 1311 | { |
1167 | struct vcpu_svm *svm = to_svm(vcpu); | 1312 | struct vcpu_svm *svm = to_svm(vcpu); |
1168 | 1313 | ||
1169 | switch (dr) { | 1314 | svm->vmcb->save.dr7 = value; |
1170 | case 0 ... 3: | ||
1171 | vcpu->arch.db[dr] = value; | ||
1172 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | ||
1173 | vcpu->arch.eff_db[dr] = value; | ||
1174 | break; | ||
1175 | case 4: | ||
1176 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1177 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1178 | /* fall through */ | ||
1179 | case 6: | ||
1180 | vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1; | ||
1181 | break; | ||
1182 | case 5: | ||
1183 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1184 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1185 | /* fall through */ | ||
1186 | case 7: | ||
1187 | vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1; | ||
1188 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
1189 | svm->vmcb->save.dr7 = vcpu->arch.dr7; | ||
1190 | vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK); | ||
1191 | } | ||
1192 | break; | ||
1193 | } | ||
1194 | |||
1195 | return EMULATE_DONE; | ||
1196 | } | 1315 | } |
1197 | 1316 | ||
1198 | static int pf_interception(struct vcpu_svm *svm) | 1317 | static int pf_interception(struct vcpu_svm *svm) |
@@ -1229,7 +1348,7 @@ static int db_interception(struct vcpu_svm *svm) | |||
1229 | } | 1348 | } |
1230 | 1349 | ||
1231 | if (svm->vcpu.guest_debug & | 1350 | if (svm->vcpu.guest_debug & |
1232 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)){ | 1351 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) { |
1233 | kvm_run->exit_reason = KVM_EXIT_DEBUG; | 1352 | kvm_run->exit_reason = KVM_EXIT_DEBUG; |
1234 | kvm_run->debug.arch.pc = | 1353 | kvm_run->debug.arch.pc = |
1235 | svm->vmcb->save.cs.base + svm->vmcb->save.rip; | 1354 | svm->vmcb->save.cs.base + svm->vmcb->save.rip; |
@@ -1263,7 +1382,22 @@ static int ud_interception(struct vcpu_svm *svm) | |||
1263 | static void svm_fpu_activate(struct kvm_vcpu *vcpu) | 1382 | static void svm_fpu_activate(struct kvm_vcpu *vcpu) |
1264 | { | 1383 | { |
1265 | struct vcpu_svm *svm = to_svm(vcpu); | 1384 | struct vcpu_svm *svm = to_svm(vcpu); |
1266 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); | 1385 | u32 excp; |
1386 | |||
1387 | if (is_nested(svm)) { | ||
1388 | u32 h_excp, n_excp; | ||
1389 | |||
1390 | h_excp = svm->nested.hsave->control.intercept_exceptions; | ||
1391 | n_excp = svm->nested.intercept_exceptions; | ||
1392 | h_excp &= ~(1 << NM_VECTOR); | ||
1393 | excp = h_excp | n_excp; | ||
1394 | } else { | ||
1395 | excp = svm->vmcb->control.intercept_exceptions; | ||
1396 | excp &= ~(1 << NM_VECTOR); | ||
1397 | } | ||
1398 | |||
1399 | svm->vmcb->control.intercept_exceptions = excp; | ||
1400 | |||
1267 | svm->vcpu.fpu_active = 1; | 1401 | svm->vcpu.fpu_active = 1; |
1268 | update_cr0_intercept(svm); | 1402 | update_cr0_intercept(svm); |
1269 | } | 1403 | } |
@@ -1304,29 +1438,23 @@ static int shutdown_interception(struct vcpu_svm *svm) | |||
1304 | 1438 | ||
1305 | static int io_interception(struct vcpu_svm *svm) | 1439 | static int io_interception(struct vcpu_svm *svm) |
1306 | { | 1440 | { |
1441 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
1307 | u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */ | 1442 | u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */ |
1308 | int size, in, string; | 1443 | int size, in, string; |
1309 | unsigned port; | 1444 | unsigned port; |
1310 | 1445 | ||
1311 | ++svm->vcpu.stat.io_exits; | 1446 | ++svm->vcpu.stat.io_exits; |
1312 | |||
1313 | svm->next_rip = svm->vmcb->control.exit_info_2; | ||
1314 | |||
1315 | string = (io_info & SVM_IOIO_STR_MASK) != 0; | 1447 | string = (io_info & SVM_IOIO_STR_MASK) != 0; |
1316 | |||
1317 | if (string) { | ||
1318 | if (emulate_instruction(&svm->vcpu, | ||
1319 | 0, 0, 0) == EMULATE_DO_MMIO) | ||
1320 | return 0; | ||
1321 | return 1; | ||
1322 | } | ||
1323 | |||
1324 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; | 1448 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; |
1449 | if (string || in) | ||
1450 | return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); | ||
1451 | |||
1325 | port = io_info >> 16; | 1452 | port = io_info >> 16; |
1326 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; | 1453 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; |
1327 | 1454 | svm->next_rip = svm->vmcb->control.exit_info_2; | |
1328 | skip_emulated_instruction(&svm->vcpu); | 1455 | skip_emulated_instruction(&svm->vcpu); |
1329 | return kvm_emulate_pio(&svm->vcpu, in, size, port); | 1456 | |
1457 | return kvm_fast_pio_out(vcpu, size, port); | ||
1330 | } | 1458 | } |
1331 | 1459 | ||
1332 | static int nmi_interception(struct vcpu_svm *svm) | 1460 | static int nmi_interception(struct vcpu_svm *svm) |
@@ -1379,6 +1507,8 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm) | |||
1379 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 1507 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
1380 | bool has_error_code, u32 error_code) | 1508 | bool has_error_code, u32 error_code) |
1381 | { | 1509 | { |
1510 | int vmexit; | ||
1511 | |||
1382 | if (!is_nested(svm)) | 1512 | if (!is_nested(svm)) |
1383 | return 0; | 1513 | return 0; |
1384 | 1514 | ||
@@ -1387,21 +1517,28 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | |||
1387 | svm->vmcb->control.exit_info_1 = error_code; | 1517 | svm->vmcb->control.exit_info_1 = error_code; |
1388 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; | 1518 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; |
1389 | 1519 | ||
1390 | return nested_svm_exit_handled(svm); | 1520 | vmexit = nested_svm_intercept(svm); |
1521 | if (vmexit == NESTED_EXIT_DONE) | ||
1522 | svm->nested.exit_required = true; | ||
1523 | |||
1524 | return vmexit; | ||
1391 | } | 1525 | } |
1392 | 1526 | ||
1393 | static inline int nested_svm_intr(struct vcpu_svm *svm) | 1527 | /* This function returns true if it is save to enable the irq window */ |
1528 | static inline bool nested_svm_intr(struct vcpu_svm *svm) | ||
1394 | { | 1529 | { |
1395 | if (!is_nested(svm)) | 1530 | if (!is_nested(svm)) |
1396 | return 0; | 1531 | return true; |
1397 | 1532 | ||
1398 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) | 1533 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) |
1399 | return 0; | 1534 | return true; |
1400 | 1535 | ||
1401 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) | 1536 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) |
1402 | return 0; | 1537 | return false; |
1403 | 1538 | ||
1404 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; | 1539 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; |
1540 | svm->vmcb->control.exit_info_1 = 0; | ||
1541 | svm->vmcb->control.exit_info_2 = 0; | ||
1405 | 1542 | ||
1406 | if (svm->nested.intercept & 1ULL) { | 1543 | if (svm->nested.intercept & 1ULL) { |
1407 | /* | 1544 | /* |
@@ -1412,21 +1549,40 @@ static inline int nested_svm_intr(struct vcpu_svm *svm) | |||
1412 | */ | 1549 | */ |
1413 | svm->nested.exit_required = true; | 1550 | svm->nested.exit_required = true; |
1414 | trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip); | 1551 | trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip); |
1415 | return 1; | 1552 | return false; |
1416 | } | 1553 | } |
1417 | 1554 | ||
1418 | return 0; | 1555 | return true; |
1556 | } | ||
1557 | |||
1558 | /* This function returns true if it is save to enable the nmi window */ | ||
1559 | static inline bool nested_svm_nmi(struct vcpu_svm *svm) | ||
1560 | { | ||
1561 | if (!is_nested(svm)) | ||
1562 | return true; | ||
1563 | |||
1564 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_NMI))) | ||
1565 | return true; | ||
1566 | |||
1567 | svm->vmcb->control.exit_code = SVM_EXIT_NMI; | ||
1568 | svm->nested.exit_required = true; | ||
1569 | |||
1570 | return false; | ||
1419 | } | 1571 | } |
1420 | 1572 | ||
1421 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx) | 1573 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) |
1422 | { | 1574 | { |
1423 | struct page *page; | 1575 | struct page *page; |
1424 | 1576 | ||
1577 | might_sleep(); | ||
1578 | |||
1425 | page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); | 1579 | page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); |
1426 | if (is_error_page(page)) | 1580 | if (is_error_page(page)) |
1427 | goto error; | 1581 | goto error; |
1428 | 1582 | ||
1429 | return kmap_atomic(page, idx); | 1583 | *_page = page; |
1584 | |||
1585 | return kmap(page); | ||
1430 | 1586 | ||
1431 | error: | 1587 | error: |
1432 | kvm_release_page_clean(page); | 1588 | kvm_release_page_clean(page); |
@@ -1435,61 +1591,55 @@ error: | |||
1435 | return NULL; | 1591 | return NULL; |
1436 | } | 1592 | } |
1437 | 1593 | ||
1438 | static void nested_svm_unmap(void *addr, enum km_type idx) | 1594 | static void nested_svm_unmap(struct page *page) |
1439 | { | 1595 | { |
1440 | struct page *page; | 1596 | kunmap(page); |
1597 | kvm_release_page_dirty(page); | ||
1598 | } | ||
1441 | 1599 | ||
1442 | if (!addr) | 1600 | static int nested_svm_intercept_ioio(struct vcpu_svm *svm) |
1443 | return; | 1601 | { |
1602 | unsigned port; | ||
1603 | u8 val, bit; | ||
1604 | u64 gpa; | ||
1444 | 1605 | ||
1445 | page = kmap_atomic_to_page(addr); | 1606 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT))) |
1607 | return NESTED_EXIT_HOST; | ||
1446 | 1608 | ||
1447 | kunmap_atomic(addr, idx); | 1609 | port = svm->vmcb->control.exit_info_1 >> 16; |
1448 | kvm_release_page_dirty(page); | 1610 | gpa = svm->nested.vmcb_iopm + (port / 8); |
1611 | bit = port % 8; | ||
1612 | val = 0; | ||
1613 | |||
1614 | if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, 1)) | ||
1615 | val &= (1 << bit); | ||
1616 | |||
1617 | return val ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; | ||
1449 | } | 1618 | } |
1450 | 1619 | ||
1451 | static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) | 1620 | static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) |
1452 | { | 1621 | { |
1453 | u32 param = svm->vmcb->control.exit_info_1 & 1; | 1622 | u32 offset, msr, value; |
1454 | u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 1623 | int write, mask; |
1455 | bool ret = false; | ||
1456 | u32 t0, t1; | ||
1457 | u8 *msrpm; | ||
1458 | 1624 | ||
1459 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) | 1625 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) |
1460 | return false; | 1626 | return NESTED_EXIT_HOST; |
1461 | |||
1462 | msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); | ||
1463 | 1627 | ||
1464 | if (!msrpm) | 1628 | msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; |
1465 | goto out; | 1629 | offset = svm_msrpm_offset(msr); |
1630 | write = svm->vmcb->control.exit_info_1 & 1; | ||
1631 | mask = 1 << ((2 * (msr & 0xf)) + write); | ||
1466 | 1632 | ||
1467 | switch (msr) { | 1633 | if (offset == MSR_INVALID) |
1468 | case 0 ... 0x1fff: | 1634 | return NESTED_EXIT_DONE; |
1469 | t0 = (msr * 2) % 8; | ||
1470 | t1 = msr / 8; | ||
1471 | break; | ||
1472 | case 0xc0000000 ... 0xc0001fff: | ||
1473 | t0 = (8192 + msr - 0xc0000000) * 2; | ||
1474 | t1 = (t0 / 8); | ||
1475 | t0 %= 8; | ||
1476 | break; | ||
1477 | case 0xc0010000 ... 0xc0011fff: | ||
1478 | t0 = (16384 + msr - 0xc0010000) * 2; | ||
1479 | t1 = (t0 / 8); | ||
1480 | t0 %= 8; | ||
1481 | break; | ||
1482 | default: | ||
1483 | ret = true; | ||
1484 | goto out; | ||
1485 | } | ||
1486 | 1635 | ||
1487 | ret = msrpm[t1] & ((1 << param) << t0); | 1636 | /* Offset is in 32 bit units but need in 8 bit units */ |
1637 | offset *= 4; | ||
1488 | 1638 | ||
1489 | out: | 1639 | if (kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + offset, &value, 4)) |
1490 | nested_svm_unmap(msrpm, KM_USER0); | 1640 | return NESTED_EXIT_DONE; |
1491 | 1641 | ||
1492 | return ret; | 1642 | return (value & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; |
1493 | } | 1643 | } |
1494 | 1644 | ||
1495 | static int nested_svm_exit_special(struct vcpu_svm *svm) | 1645 | static int nested_svm_exit_special(struct vcpu_svm *svm) |
@@ -1500,16 +1650,19 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) | |||
1500 | case SVM_EXIT_INTR: | 1650 | case SVM_EXIT_INTR: |
1501 | case SVM_EXIT_NMI: | 1651 | case SVM_EXIT_NMI: |
1502 | return NESTED_EXIT_HOST; | 1652 | return NESTED_EXIT_HOST; |
1503 | /* For now we are always handling NPFs when using them */ | ||
1504 | case SVM_EXIT_NPF: | 1653 | case SVM_EXIT_NPF: |
1654 | /* For now we are always handling NPFs when using them */ | ||
1505 | if (npt_enabled) | 1655 | if (npt_enabled) |
1506 | return NESTED_EXIT_HOST; | 1656 | return NESTED_EXIT_HOST; |
1507 | break; | 1657 | break; |
1508 | /* When we're shadowing, trap PFs */ | ||
1509 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: | 1658 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: |
1659 | /* When we're shadowing, trap PFs */ | ||
1510 | if (!npt_enabled) | 1660 | if (!npt_enabled) |
1511 | return NESTED_EXIT_HOST; | 1661 | return NESTED_EXIT_HOST; |
1512 | break; | 1662 | break; |
1663 | case SVM_EXIT_EXCP_BASE + NM_VECTOR: | ||
1664 | nm_interception(svm); | ||
1665 | break; | ||
1513 | default: | 1666 | default: |
1514 | break; | 1667 | break; |
1515 | } | 1668 | } |
@@ -1520,7 +1673,7 @@ static int nested_svm_exit_special(struct vcpu_svm *svm) | |||
1520 | /* | 1673 | /* |
1521 | * If this function returns true, this #vmexit was already handled | 1674 | * If this function returns true, this #vmexit was already handled |
1522 | */ | 1675 | */ |
1523 | static int nested_svm_exit_handled(struct vcpu_svm *svm) | 1676 | static int nested_svm_intercept(struct vcpu_svm *svm) |
1524 | { | 1677 | { |
1525 | u32 exit_code = svm->vmcb->control.exit_code; | 1678 | u32 exit_code = svm->vmcb->control.exit_code; |
1526 | int vmexit = NESTED_EXIT_HOST; | 1679 | int vmexit = NESTED_EXIT_HOST; |
@@ -1529,6 +1682,9 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm) | |||
1529 | case SVM_EXIT_MSR: | 1682 | case SVM_EXIT_MSR: |
1530 | vmexit = nested_svm_exit_handled_msr(svm); | 1683 | vmexit = nested_svm_exit_handled_msr(svm); |
1531 | break; | 1684 | break; |
1685 | case SVM_EXIT_IOIO: | ||
1686 | vmexit = nested_svm_intercept_ioio(svm); | ||
1687 | break; | ||
1532 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { | 1688 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { |
1533 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); | 1689 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); |
1534 | if (svm->nested.intercept_cr_read & cr_bits) | 1690 | if (svm->nested.intercept_cr_read & cr_bits) |
@@ -1566,9 +1722,17 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm) | |||
1566 | } | 1722 | } |
1567 | } | 1723 | } |
1568 | 1724 | ||
1569 | if (vmexit == NESTED_EXIT_DONE) { | 1725 | return vmexit; |
1726 | } | ||
1727 | |||
1728 | static int nested_svm_exit_handled(struct vcpu_svm *svm) | ||
1729 | { | ||
1730 | int vmexit; | ||
1731 | |||
1732 | vmexit = nested_svm_intercept(svm); | ||
1733 | |||
1734 | if (vmexit == NESTED_EXIT_DONE) | ||
1570 | nested_svm_vmexit(svm); | 1735 | nested_svm_vmexit(svm); |
1571 | } | ||
1572 | 1736 | ||
1573 | return vmexit; | 1737 | return vmexit; |
1574 | } | 1738 | } |
@@ -1610,6 +1774,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1610 | struct vmcb *nested_vmcb; | 1774 | struct vmcb *nested_vmcb; |
1611 | struct vmcb *hsave = svm->nested.hsave; | 1775 | struct vmcb *hsave = svm->nested.hsave; |
1612 | struct vmcb *vmcb = svm->vmcb; | 1776 | struct vmcb *vmcb = svm->vmcb; |
1777 | struct page *page; | ||
1613 | 1778 | ||
1614 | trace_kvm_nested_vmexit_inject(vmcb->control.exit_code, | 1779 | trace_kvm_nested_vmexit_inject(vmcb->control.exit_code, |
1615 | vmcb->control.exit_info_1, | 1780 | vmcb->control.exit_info_1, |
@@ -1617,10 +1782,13 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1617 | vmcb->control.exit_int_info, | 1782 | vmcb->control.exit_int_info, |
1618 | vmcb->control.exit_int_info_err); | 1783 | vmcb->control.exit_int_info_err); |
1619 | 1784 | ||
1620 | nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0); | 1785 | nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, &page); |
1621 | if (!nested_vmcb) | 1786 | if (!nested_vmcb) |
1622 | return 1; | 1787 | return 1; |
1623 | 1788 | ||
1789 | /* Exit nested SVM mode */ | ||
1790 | svm->nested.vmcb = 0; | ||
1791 | |||
1624 | /* Give the current vmcb to the guest */ | 1792 | /* Give the current vmcb to the guest */ |
1625 | disable_gif(svm); | 1793 | disable_gif(svm); |
1626 | 1794 | ||
@@ -1630,9 +1798,13 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1630 | nested_vmcb->save.ds = vmcb->save.ds; | 1798 | nested_vmcb->save.ds = vmcb->save.ds; |
1631 | nested_vmcb->save.gdtr = vmcb->save.gdtr; | 1799 | nested_vmcb->save.gdtr = vmcb->save.gdtr; |
1632 | nested_vmcb->save.idtr = vmcb->save.idtr; | 1800 | nested_vmcb->save.idtr = vmcb->save.idtr; |
1801 | nested_vmcb->save.cr0 = kvm_read_cr0(&svm->vcpu); | ||
1633 | if (npt_enabled) | 1802 | if (npt_enabled) |
1634 | nested_vmcb->save.cr3 = vmcb->save.cr3; | 1803 | nested_vmcb->save.cr3 = vmcb->save.cr3; |
1804 | else | ||
1805 | nested_vmcb->save.cr3 = svm->vcpu.arch.cr3; | ||
1635 | nested_vmcb->save.cr2 = vmcb->save.cr2; | 1806 | nested_vmcb->save.cr2 = vmcb->save.cr2; |
1807 | nested_vmcb->save.cr4 = svm->vcpu.arch.cr4; | ||
1636 | nested_vmcb->save.rflags = vmcb->save.rflags; | 1808 | nested_vmcb->save.rflags = vmcb->save.rflags; |
1637 | nested_vmcb->save.rip = vmcb->save.rip; | 1809 | nested_vmcb->save.rip = vmcb->save.rip; |
1638 | nested_vmcb->save.rsp = vmcb->save.rsp; | 1810 | nested_vmcb->save.rsp = vmcb->save.rsp; |
@@ -1704,10 +1876,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1704 | svm->vmcb->save.cpl = 0; | 1876 | svm->vmcb->save.cpl = 0; |
1705 | svm->vmcb->control.exit_int_info = 0; | 1877 | svm->vmcb->control.exit_int_info = 0; |
1706 | 1878 | ||
1707 | /* Exit nested SVM mode */ | 1879 | nested_svm_unmap(page); |
1708 | svm->nested.vmcb = 0; | ||
1709 | |||
1710 | nested_svm_unmap(nested_vmcb, KM_USER0); | ||
1711 | 1880 | ||
1712 | kvm_mmu_reset_context(&svm->vcpu); | 1881 | kvm_mmu_reset_context(&svm->vcpu); |
1713 | kvm_mmu_load(&svm->vcpu); | 1882 | kvm_mmu_load(&svm->vcpu); |
@@ -1717,19 +1886,33 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1717 | 1886 | ||
1718 | static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) | 1887 | static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) |
1719 | { | 1888 | { |
1720 | u32 *nested_msrpm; | 1889 | /* |
1890 | * This function merges the msr permission bitmaps of kvm and the | ||
1891 | * nested vmcb. It is omptimized in that it only merges the parts where | ||
1892 | * the kvm msr permission bitmap may contain zero bits | ||
1893 | */ | ||
1721 | int i; | 1894 | int i; |
1722 | 1895 | ||
1723 | nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); | 1896 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) |
1724 | if (!nested_msrpm) | 1897 | return true; |
1725 | return false; | ||
1726 | 1898 | ||
1727 | for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) | 1899 | for (i = 0; i < MSRPM_OFFSETS; i++) { |
1728 | svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; | 1900 | u32 value, p; |
1901 | u64 offset; | ||
1729 | 1902 | ||
1730 | svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); | 1903 | if (msrpm_offsets[i] == 0xffffffff) |
1904 | break; | ||
1905 | |||
1906 | p = msrpm_offsets[i]; | ||
1907 | offset = svm->nested.vmcb_msrpm + (p * 4); | ||
1908 | |||
1909 | if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) | ||
1910 | return false; | ||
1911 | |||
1912 | svm->nested.msrpm[p] = svm->msrpm[p] | value; | ||
1913 | } | ||
1731 | 1914 | ||
1732 | nested_svm_unmap(nested_msrpm, KM_USER0); | 1915 | svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); |
1733 | 1916 | ||
1734 | return true; | 1917 | return true; |
1735 | } | 1918 | } |
@@ -1739,26 +1922,34 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
1739 | struct vmcb *nested_vmcb; | 1922 | struct vmcb *nested_vmcb; |
1740 | struct vmcb *hsave = svm->nested.hsave; | 1923 | struct vmcb *hsave = svm->nested.hsave; |
1741 | struct vmcb *vmcb = svm->vmcb; | 1924 | struct vmcb *vmcb = svm->vmcb; |
1925 | struct page *page; | ||
1926 | u64 vmcb_gpa; | ||
1927 | |||
1928 | vmcb_gpa = svm->vmcb->save.rax; | ||
1742 | 1929 | ||
1743 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); | 1930 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); |
1744 | if (!nested_vmcb) | 1931 | if (!nested_vmcb) |
1745 | return false; | 1932 | return false; |
1746 | 1933 | ||
1747 | /* nested_vmcb is our indicator if nested SVM is activated */ | 1934 | trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, vmcb_gpa, |
1748 | svm->nested.vmcb = svm->vmcb->save.rax; | ||
1749 | |||
1750 | trace_kvm_nested_vmrun(svm->vmcb->save.rip - 3, svm->nested.vmcb, | ||
1751 | nested_vmcb->save.rip, | 1935 | nested_vmcb->save.rip, |
1752 | nested_vmcb->control.int_ctl, | 1936 | nested_vmcb->control.int_ctl, |
1753 | nested_vmcb->control.event_inj, | 1937 | nested_vmcb->control.event_inj, |
1754 | nested_vmcb->control.nested_ctl); | 1938 | nested_vmcb->control.nested_ctl); |
1755 | 1939 | ||
1940 | trace_kvm_nested_intercepts(nested_vmcb->control.intercept_cr_read, | ||
1941 | nested_vmcb->control.intercept_cr_write, | ||
1942 | nested_vmcb->control.intercept_exceptions, | ||
1943 | nested_vmcb->control.intercept); | ||
1944 | |||
1756 | /* Clear internal status */ | 1945 | /* Clear internal status */ |
1757 | kvm_clear_exception_queue(&svm->vcpu); | 1946 | kvm_clear_exception_queue(&svm->vcpu); |
1758 | kvm_clear_interrupt_queue(&svm->vcpu); | 1947 | kvm_clear_interrupt_queue(&svm->vcpu); |
1759 | 1948 | ||
1760 | /* Save the old vmcb, so we don't need to pick what we save, but | 1949 | /* |
1761 | can restore everything when a VMEXIT occurs */ | 1950 | * Save the old vmcb, so we don't need to pick what we save, but can |
1951 | * restore everything when a VMEXIT occurs | ||
1952 | */ | ||
1762 | hsave->save.es = vmcb->save.es; | 1953 | hsave->save.es = vmcb->save.es; |
1763 | hsave->save.cs = vmcb->save.cs; | 1954 | hsave->save.cs = vmcb->save.cs; |
1764 | hsave->save.ss = vmcb->save.ss; | 1955 | hsave->save.ss = vmcb->save.ss; |
@@ -1798,14 +1989,17 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
1798 | if (npt_enabled) { | 1989 | if (npt_enabled) { |
1799 | svm->vmcb->save.cr3 = nested_vmcb->save.cr3; | 1990 | svm->vmcb->save.cr3 = nested_vmcb->save.cr3; |
1800 | svm->vcpu.arch.cr3 = nested_vmcb->save.cr3; | 1991 | svm->vcpu.arch.cr3 = nested_vmcb->save.cr3; |
1801 | } else { | 1992 | } else |
1802 | kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); | 1993 | kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); |
1803 | kvm_mmu_reset_context(&svm->vcpu); | 1994 | |
1804 | } | 1995 | /* Guest paging mode is active - reset mmu */ |
1996 | kvm_mmu_reset_context(&svm->vcpu); | ||
1997 | |||
1805 | svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2; | 1998 | svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2; |
1806 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); | 1999 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); |
1807 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); | 2000 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); |
1808 | kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); | 2001 | kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); |
2002 | |||
1809 | /* In case we don't even reach vcpu_run, the fields are not updated */ | 2003 | /* In case we don't even reach vcpu_run, the fields are not updated */ |
1810 | svm->vmcb->save.rax = nested_vmcb->save.rax; | 2004 | svm->vmcb->save.rax = nested_vmcb->save.rax; |
1811 | svm->vmcb->save.rsp = nested_vmcb->save.rsp; | 2005 | svm->vmcb->save.rsp = nested_vmcb->save.rsp; |
@@ -1814,22 +2008,8 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
1814 | svm->vmcb->save.dr6 = nested_vmcb->save.dr6; | 2008 | svm->vmcb->save.dr6 = nested_vmcb->save.dr6; |
1815 | svm->vmcb->save.cpl = nested_vmcb->save.cpl; | 2009 | svm->vmcb->save.cpl = nested_vmcb->save.cpl; |
1816 | 2010 | ||
1817 | /* We don't want a nested guest to be more powerful than the guest, | 2011 | svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa & ~0x0fffULL; |
1818 | so all intercepts are ORed */ | 2012 | svm->nested.vmcb_iopm = nested_vmcb->control.iopm_base_pa & ~0x0fffULL; |
1819 | svm->vmcb->control.intercept_cr_read |= | ||
1820 | nested_vmcb->control.intercept_cr_read; | ||
1821 | svm->vmcb->control.intercept_cr_write |= | ||
1822 | nested_vmcb->control.intercept_cr_write; | ||
1823 | svm->vmcb->control.intercept_dr_read |= | ||
1824 | nested_vmcb->control.intercept_dr_read; | ||
1825 | svm->vmcb->control.intercept_dr_write |= | ||
1826 | nested_vmcb->control.intercept_dr_write; | ||
1827 | svm->vmcb->control.intercept_exceptions |= | ||
1828 | nested_vmcb->control.intercept_exceptions; | ||
1829 | |||
1830 | svm->vmcb->control.intercept |= nested_vmcb->control.intercept; | ||
1831 | |||
1832 | svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; | ||
1833 | 2013 | ||
1834 | /* cache intercepts */ | 2014 | /* cache intercepts */ |
1835 | svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read; | 2015 | svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read; |
@@ -1846,13 +2026,40 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
1846 | else | 2026 | else |
1847 | svm->vcpu.arch.hflags &= ~HF_VINTR_MASK; | 2027 | svm->vcpu.arch.hflags &= ~HF_VINTR_MASK; |
1848 | 2028 | ||
2029 | if (svm->vcpu.arch.hflags & HF_VINTR_MASK) { | ||
2030 | /* We only want the cr8 intercept bits of the guest */ | ||
2031 | svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK; | ||
2032 | svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK; | ||
2033 | } | ||
2034 | |||
2035 | /* | ||
2036 | * We don't want a nested guest to be more powerful than the guest, so | ||
2037 | * all intercepts are ORed | ||
2038 | */ | ||
2039 | svm->vmcb->control.intercept_cr_read |= | ||
2040 | nested_vmcb->control.intercept_cr_read; | ||
2041 | svm->vmcb->control.intercept_cr_write |= | ||
2042 | nested_vmcb->control.intercept_cr_write; | ||
2043 | svm->vmcb->control.intercept_dr_read |= | ||
2044 | nested_vmcb->control.intercept_dr_read; | ||
2045 | svm->vmcb->control.intercept_dr_write |= | ||
2046 | nested_vmcb->control.intercept_dr_write; | ||
2047 | svm->vmcb->control.intercept_exceptions |= | ||
2048 | nested_vmcb->control.intercept_exceptions; | ||
2049 | |||
2050 | svm->vmcb->control.intercept |= nested_vmcb->control.intercept; | ||
2051 | |||
2052 | svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl; | ||
1849 | svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; | 2053 | svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; |
1850 | svm->vmcb->control.int_state = nested_vmcb->control.int_state; | 2054 | svm->vmcb->control.int_state = nested_vmcb->control.int_state; |
1851 | svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset; | 2055 | svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset; |
1852 | svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; | 2056 | svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; |
1853 | svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; | 2057 | svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; |
1854 | 2058 | ||
1855 | nested_svm_unmap(nested_vmcb, KM_USER0); | 2059 | nested_svm_unmap(page); |
2060 | |||
2061 | /* nested_vmcb is our indicator if nested SVM is activated */ | ||
2062 | svm->nested.vmcb = vmcb_gpa; | ||
1856 | 2063 | ||
1857 | enable_gif(svm); | 2064 | enable_gif(svm); |
1858 | 2065 | ||
@@ -1878,6 +2085,7 @@ static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) | |||
1878 | static int vmload_interception(struct vcpu_svm *svm) | 2085 | static int vmload_interception(struct vcpu_svm *svm) |
1879 | { | 2086 | { |
1880 | struct vmcb *nested_vmcb; | 2087 | struct vmcb *nested_vmcb; |
2088 | struct page *page; | ||
1881 | 2089 | ||
1882 | if (nested_svm_check_permissions(svm)) | 2090 | if (nested_svm_check_permissions(svm)) |
1883 | return 1; | 2091 | return 1; |
@@ -1885,12 +2093,12 @@ static int vmload_interception(struct vcpu_svm *svm) | |||
1885 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 2093 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
1886 | skip_emulated_instruction(&svm->vcpu); | 2094 | skip_emulated_instruction(&svm->vcpu); |
1887 | 2095 | ||
1888 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); | 2096 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); |
1889 | if (!nested_vmcb) | 2097 | if (!nested_vmcb) |
1890 | return 1; | 2098 | return 1; |
1891 | 2099 | ||
1892 | nested_svm_vmloadsave(nested_vmcb, svm->vmcb); | 2100 | nested_svm_vmloadsave(nested_vmcb, svm->vmcb); |
1893 | nested_svm_unmap(nested_vmcb, KM_USER0); | 2101 | nested_svm_unmap(page); |
1894 | 2102 | ||
1895 | return 1; | 2103 | return 1; |
1896 | } | 2104 | } |
@@ -1898,6 +2106,7 @@ static int vmload_interception(struct vcpu_svm *svm) | |||
1898 | static int vmsave_interception(struct vcpu_svm *svm) | 2106 | static int vmsave_interception(struct vcpu_svm *svm) |
1899 | { | 2107 | { |
1900 | struct vmcb *nested_vmcb; | 2108 | struct vmcb *nested_vmcb; |
2109 | struct page *page; | ||
1901 | 2110 | ||
1902 | if (nested_svm_check_permissions(svm)) | 2111 | if (nested_svm_check_permissions(svm)) |
1903 | return 1; | 2112 | return 1; |
@@ -1905,12 +2114,12 @@ static int vmsave_interception(struct vcpu_svm *svm) | |||
1905 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 2114 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
1906 | skip_emulated_instruction(&svm->vcpu); | 2115 | skip_emulated_instruction(&svm->vcpu); |
1907 | 2116 | ||
1908 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); | 2117 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page); |
1909 | if (!nested_vmcb) | 2118 | if (!nested_vmcb) |
1910 | return 1; | 2119 | return 1; |
1911 | 2120 | ||
1912 | nested_svm_vmloadsave(svm->vmcb, nested_vmcb); | 2121 | nested_svm_vmloadsave(svm->vmcb, nested_vmcb); |
1913 | nested_svm_unmap(nested_vmcb, KM_USER0); | 2122 | nested_svm_unmap(page); |
1914 | 2123 | ||
1915 | return 1; | 2124 | return 1; |
1916 | } | 2125 | } |
@@ -2013,6 +2222,8 @@ static int task_switch_interception(struct vcpu_svm *svm) | |||
2013 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK; | 2222 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK; |
2014 | uint32_t idt_v = | 2223 | uint32_t idt_v = |
2015 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID; | 2224 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID; |
2225 | bool has_error_code = false; | ||
2226 | u32 error_code = 0; | ||
2016 | 2227 | ||
2017 | tss_selector = (u16)svm->vmcb->control.exit_info_1; | 2228 | tss_selector = (u16)svm->vmcb->control.exit_info_1; |
2018 | 2229 | ||
@@ -2033,6 +2244,12 @@ static int task_switch_interception(struct vcpu_svm *svm) | |||
2033 | svm->vcpu.arch.nmi_injected = false; | 2244 | svm->vcpu.arch.nmi_injected = false; |
2034 | break; | 2245 | break; |
2035 | case SVM_EXITINTINFO_TYPE_EXEPT: | 2246 | case SVM_EXITINTINFO_TYPE_EXEPT: |
2247 | if (svm->vmcb->control.exit_info_2 & | ||
2248 | (1ULL << SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE)) { | ||
2249 | has_error_code = true; | ||
2250 | error_code = | ||
2251 | (u32)svm->vmcb->control.exit_info_2; | ||
2252 | } | ||
2036 | kvm_clear_exception_queue(&svm->vcpu); | 2253 | kvm_clear_exception_queue(&svm->vcpu); |
2037 | break; | 2254 | break; |
2038 | case SVM_EXITINTINFO_TYPE_INTR: | 2255 | case SVM_EXITINTINFO_TYPE_INTR: |
@@ -2049,7 +2266,14 @@ static int task_switch_interception(struct vcpu_svm *svm) | |||
2049 | (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) | 2266 | (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) |
2050 | skip_emulated_instruction(&svm->vcpu); | 2267 | skip_emulated_instruction(&svm->vcpu); |
2051 | 2268 | ||
2052 | return kvm_task_switch(&svm->vcpu, tss_selector, reason); | 2269 | if (kvm_task_switch(&svm->vcpu, tss_selector, reason, |
2270 | has_error_code, error_code) == EMULATE_FAIL) { | ||
2271 | svm->vcpu.run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
2272 | svm->vcpu.run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||
2273 | svm->vcpu.run->internal.ndata = 0; | ||
2274 | return 0; | ||
2275 | } | ||
2276 | return 1; | ||
2053 | } | 2277 | } |
2054 | 2278 | ||
2055 | static int cpuid_interception(struct vcpu_svm *svm) | 2279 | static int cpuid_interception(struct vcpu_svm *svm) |
@@ -2140,9 +2364,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
2140 | case MSR_IA32_SYSENTER_ESP: | 2364 | case MSR_IA32_SYSENTER_ESP: |
2141 | *data = svm->sysenter_esp; | 2365 | *data = svm->sysenter_esp; |
2142 | break; | 2366 | break; |
2143 | /* Nobody will change the following 5 values in the VMCB so | 2367 | /* |
2144 | we can safely return them on rdmsr. They will always be 0 | 2368 | * Nobody will change the following 5 values in the VMCB so we can |
2145 | until LBRV is implemented. */ | 2369 | * safely return them on rdmsr. They will always be 0 until LBRV is |
2370 | * implemented. | ||
2371 | */ | ||
2146 | case MSR_IA32_DEBUGCTLMSR: | 2372 | case MSR_IA32_DEBUGCTLMSR: |
2147 | *data = svm->vmcb->save.dbgctl; | 2373 | *data = svm->vmcb->save.dbgctl; |
2148 | break; | 2374 | break; |
@@ -2162,7 +2388,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
2162 | *data = svm->nested.hsave_msr; | 2388 | *data = svm->nested.hsave_msr; |
2163 | break; | 2389 | break; |
2164 | case MSR_VM_CR: | 2390 | case MSR_VM_CR: |
2165 | *data = 0; | 2391 | *data = svm->nested.vm_cr_msr; |
2166 | break; | 2392 | break; |
2167 | case MSR_IA32_UCODE_REV: | 2393 | case MSR_IA32_UCODE_REV: |
2168 | *data = 0x01000065; | 2394 | *data = 0x01000065; |
@@ -2192,6 +2418,31 @@ static int rdmsr_interception(struct vcpu_svm *svm) | |||
2192 | return 1; | 2418 | return 1; |
2193 | } | 2419 | } |
2194 | 2420 | ||
2421 | static int svm_set_vm_cr(struct kvm_vcpu *vcpu, u64 data) | ||
2422 | { | ||
2423 | struct vcpu_svm *svm = to_svm(vcpu); | ||
2424 | int svm_dis, chg_mask; | ||
2425 | |||
2426 | if (data & ~SVM_VM_CR_VALID_MASK) | ||
2427 | return 1; | ||
2428 | |||
2429 | chg_mask = SVM_VM_CR_VALID_MASK; | ||
2430 | |||
2431 | if (svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK) | ||
2432 | chg_mask &= ~(SVM_VM_CR_SVM_LOCK_MASK | SVM_VM_CR_SVM_DIS_MASK); | ||
2433 | |||
2434 | svm->nested.vm_cr_msr &= ~chg_mask; | ||
2435 | svm->nested.vm_cr_msr |= (data & chg_mask); | ||
2436 | |||
2437 | svm_dis = svm->nested.vm_cr_msr & SVM_VM_CR_SVM_DIS_MASK; | ||
2438 | |||
2439 | /* check for svm_disable while efer.svme is set */ | ||
2440 | if (svm_dis && (vcpu->arch.efer & EFER_SVME)) | ||
2441 | return 1; | ||
2442 | |||
2443 | return 0; | ||
2444 | } | ||
2445 | |||
2195 | static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | 2446 | static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) |
2196 | { | 2447 | { |
2197 | struct vcpu_svm *svm = to_svm(vcpu); | 2448 | struct vcpu_svm *svm = to_svm(vcpu); |
@@ -2258,6 +2509,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
2258 | svm->nested.hsave_msr = data; | 2509 | svm->nested.hsave_msr = data; |
2259 | break; | 2510 | break; |
2260 | case MSR_VM_CR: | 2511 | case MSR_VM_CR: |
2512 | return svm_set_vm_cr(vcpu, data); | ||
2261 | case MSR_VM_IGNNE: | 2513 | case MSR_VM_IGNNE: |
2262 | pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); | 2514 | pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); |
2263 | break; | 2515 | break; |
@@ -2321,16 +2573,16 @@ static int pause_interception(struct vcpu_svm *svm) | |||
2321 | } | 2573 | } |
2322 | 2574 | ||
2323 | static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | 2575 | static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { |
2324 | [SVM_EXIT_READ_CR0] = emulate_on_interception, | 2576 | [SVM_EXIT_READ_CR0] = emulate_on_interception, |
2325 | [SVM_EXIT_READ_CR3] = emulate_on_interception, | 2577 | [SVM_EXIT_READ_CR3] = emulate_on_interception, |
2326 | [SVM_EXIT_READ_CR4] = emulate_on_interception, | 2578 | [SVM_EXIT_READ_CR4] = emulate_on_interception, |
2327 | [SVM_EXIT_READ_CR8] = emulate_on_interception, | 2579 | [SVM_EXIT_READ_CR8] = emulate_on_interception, |
2328 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, | 2580 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, |
2329 | [SVM_EXIT_WRITE_CR0] = emulate_on_interception, | 2581 | [SVM_EXIT_WRITE_CR0] = emulate_on_interception, |
2330 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, | 2582 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, |
2331 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, | 2583 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, |
2332 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, | 2584 | [SVM_EXIT_WRITE_CR8] = cr8_write_interception, |
2333 | [SVM_EXIT_READ_DR0] = emulate_on_interception, | 2585 | [SVM_EXIT_READ_DR0] = emulate_on_interception, |
2334 | [SVM_EXIT_READ_DR1] = emulate_on_interception, | 2586 | [SVM_EXIT_READ_DR1] = emulate_on_interception, |
2335 | [SVM_EXIT_READ_DR2] = emulate_on_interception, | 2587 | [SVM_EXIT_READ_DR2] = emulate_on_interception, |
2336 | [SVM_EXIT_READ_DR3] = emulate_on_interception, | 2588 | [SVM_EXIT_READ_DR3] = emulate_on_interception, |
@@ -2349,15 +2601,14 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2349 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, | 2601 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, |
2350 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, | 2602 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, |
2351 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, | 2603 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, |
2352 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, | 2604 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, |
2353 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, | 2605 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, |
2354 | [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, | 2606 | [SVM_EXIT_EXCP_BASE + MC_VECTOR] = mc_interception, |
2355 | [SVM_EXIT_INTR] = intr_interception, | 2607 | [SVM_EXIT_INTR] = intr_interception, |
2356 | [SVM_EXIT_NMI] = nmi_interception, | 2608 | [SVM_EXIT_NMI] = nmi_interception, |
2357 | [SVM_EXIT_SMI] = nop_on_interception, | 2609 | [SVM_EXIT_SMI] = nop_on_interception, |
2358 | [SVM_EXIT_INIT] = nop_on_interception, | 2610 | [SVM_EXIT_INIT] = nop_on_interception, |
2359 | [SVM_EXIT_VINTR] = interrupt_window_interception, | 2611 | [SVM_EXIT_VINTR] = interrupt_window_interception, |
2360 | /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ | ||
2361 | [SVM_EXIT_CPUID] = cpuid_interception, | 2612 | [SVM_EXIT_CPUID] = cpuid_interception, |
2362 | [SVM_EXIT_IRET] = iret_interception, | 2613 | [SVM_EXIT_IRET] = iret_interception, |
2363 | [SVM_EXIT_INVD] = emulate_on_interception, | 2614 | [SVM_EXIT_INVD] = emulate_on_interception, |
@@ -2365,7 +2616,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2365 | [SVM_EXIT_HLT] = halt_interception, | 2616 | [SVM_EXIT_HLT] = halt_interception, |
2366 | [SVM_EXIT_INVLPG] = invlpg_interception, | 2617 | [SVM_EXIT_INVLPG] = invlpg_interception, |
2367 | [SVM_EXIT_INVLPGA] = invlpga_interception, | 2618 | [SVM_EXIT_INVLPGA] = invlpga_interception, |
2368 | [SVM_EXIT_IOIO] = io_interception, | 2619 | [SVM_EXIT_IOIO] = io_interception, |
2369 | [SVM_EXIT_MSR] = msr_interception, | 2620 | [SVM_EXIT_MSR] = msr_interception, |
2370 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, | 2621 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, |
2371 | [SVM_EXIT_SHUTDOWN] = shutdown_interception, | 2622 | [SVM_EXIT_SHUTDOWN] = shutdown_interception, |
@@ -2388,7 +2639,7 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
2388 | struct kvm_run *kvm_run = vcpu->run; | 2639 | struct kvm_run *kvm_run = vcpu->run; |
2389 | u32 exit_code = svm->vmcb->control.exit_code; | 2640 | u32 exit_code = svm->vmcb->control.exit_code; |
2390 | 2641 | ||
2391 | trace_kvm_exit(exit_code, svm->vmcb->save.rip); | 2642 | trace_kvm_exit(exit_code, vcpu); |
2392 | 2643 | ||
2393 | if (unlikely(svm->nested.exit_required)) { | 2644 | if (unlikely(svm->nested.exit_required)) { |
2394 | nested_svm_vmexit(svm); | 2645 | nested_svm_vmexit(svm); |
@@ -2506,6 +2757,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | |||
2506 | { | 2757 | { |
2507 | struct vcpu_svm *svm = to_svm(vcpu); | 2758 | struct vcpu_svm *svm = to_svm(vcpu); |
2508 | 2759 | ||
2760 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | ||
2761 | return; | ||
2762 | |||
2509 | if (irr == -1) | 2763 | if (irr == -1) |
2510 | return; | 2764 | return; |
2511 | 2765 | ||
@@ -2563,13 +2817,13 @@ static void enable_irq_window(struct kvm_vcpu *vcpu) | |||
2563 | { | 2817 | { |
2564 | struct vcpu_svm *svm = to_svm(vcpu); | 2818 | struct vcpu_svm *svm = to_svm(vcpu); |
2565 | 2819 | ||
2566 | nested_svm_intr(svm); | 2820 | /* |
2567 | 2821 | * In case GIF=0 we can't rely on the CPU to tell us when GIF becomes | |
2568 | /* In case GIF=0 we can't rely on the CPU to tell us when | 2822 | * 1, because that's a separate STGI/VMRUN intercept. The next time we |
2569 | * GIF becomes 1, because that's a separate STGI/VMRUN intercept. | 2823 | * get that intercept, this function will be called again though and |
2570 | * The next time we get that intercept, this function will be | 2824 | * we'll get the vintr intercept. |
2571 | * called again though and we'll get the vintr intercept. */ | 2825 | */ |
2572 | if (gif_set(svm)) { | 2826 | if (gif_set(svm) && nested_svm_intr(svm)) { |
2573 | svm_set_vintr(svm); | 2827 | svm_set_vintr(svm); |
2574 | svm_inject_irq(svm, 0x0); | 2828 | svm_inject_irq(svm, 0x0); |
2575 | } | 2829 | } |
@@ -2583,12 +2837,15 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
2583 | == HF_NMI_MASK) | 2837 | == HF_NMI_MASK) |
2584 | return; /* IRET will cause a vm exit */ | 2838 | return; /* IRET will cause a vm exit */ |
2585 | 2839 | ||
2586 | /* Something prevents NMI from been injected. Single step over | 2840 | /* |
2587 | possible problem (IRET or exception injection or interrupt | 2841 | * Something prevents NMI from been injected. Single step over possible |
2588 | shadow) */ | 2842 | * problem (IRET or exception injection or interrupt shadow) |
2589 | svm->nmi_singlestep = true; | 2843 | */ |
2590 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); | 2844 | if (gif_set(svm) && nested_svm_nmi(svm)) { |
2591 | update_db_intercept(vcpu); | 2845 | svm->nmi_singlestep = true; |
2846 | svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); | ||
2847 | update_db_intercept(vcpu); | ||
2848 | } | ||
2592 | } | 2849 | } |
2593 | 2850 | ||
2594 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) | 2851 | static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr) |
@@ -2609,6 +2866,9 @@ static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu) | |||
2609 | { | 2866 | { |
2610 | struct vcpu_svm *svm = to_svm(vcpu); | 2867 | struct vcpu_svm *svm = to_svm(vcpu); |
2611 | 2868 | ||
2869 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | ||
2870 | return; | ||
2871 | |||
2612 | if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) { | 2872 | if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) { |
2613 | int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; | 2873 | int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK; |
2614 | kvm_set_cr8(vcpu, cr8); | 2874 | kvm_set_cr8(vcpu, cr8); |
@@ -2620,6 +2880,9 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu) | |||
2620 | struct vcpu_svm *svm = to_svm(vcpu); | 2880 | struct vcpu_svm *svm = to_svm(vcpu); |
2621 | u64 cr8; | 2881 | u64 cr8; |
2622 | 2882 | ||
2883 | if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK)) | ||
2884 | return; | ||
2885 | |||
2623 | cr8 = kvm_get_cr8(vcpu); | 2886 | cr8 = kvm_get_cr8(vcpu); |
2624 | svm->vmcb->control.int_ctl &= ~V_TPR_MASK; | 2887 | svm->vmcb->control.int_ctl &= ~V_TPR_MASK; |
2625 | svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK; | 2888 | svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK; |
@@ -2630,6 +2893,9 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
2630 | u8 vector; | 2893 | u8 vector; |
2631 | int type; | 2894 | int type; |
2632 | u32 exitintinfo = svm->vmcb->control.exit_int_info; | 2895 | u32 exitintinfo = svm->vmcb->control.exit_int_info; |
2896 | unsigned int3_injected = svm->int3_injected; | ||
2897 | |||
2898 | svm->int3_injected = 0; | ||
2633 | 2899 | ||
2634 | if (svm->vcpu.arch.hflags & HF_IRET_MASK) | 2900 | if (svm->vcpu.arch.hflags & HF_IRET_MASK) |
2635 | svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); | 2901 | svm->vcpu.arch.hflags &= ~(HF_NMI_MASK | HF_IRET_MASK); |
@@ -2649,12 +2915,21 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
2649 | svm->vcpu.arch.nmi_injected = true; | 2915 | svm->vcpu.arch.nmi_injected = true; |
2650 | break; | 2916 | break; |
2651 | case SVM_EXITINTINFO_TYPE_EXEPT: | 2917 | case SVM_EXITINTINFO_TYPE_EXEPT: |
2652 | /* In case of software exception do not reinject an exception | ||
2653 | vector, but re-execute and instruction instead */ | ||
2654 | if (is_nested(svm)) | 2918 | if (is_nested(svm)) |
2655 | break; | 2919 | break; |
2656 | if (kvm_exception_is_soft(vector)) | 2920 | /* |
2921 | * In case of software exceptions, do not reinject the vector, | ||
2922 | * but re-execute the instruction instead. Rewind RIP first | ||
2923 | * if we emulated INT3 before. | ||
2924 | */ | ||
2925 | if (kvm_exception_is_soft(vector)) { | ||
2926 | if (vector == BP_VECTOR && int3_injected && | ||
2927 | kvm_is_linear_rip(&svm->vcpu, svm->int3_rip)) | ||
2928 | kvm_rip_write(&svm->vcpu, | ||
2929 | kvm_rip_read(&svm->vcpu) - | ||
2930 | int3_injected); | ||
2657 | break; | 2931 | break; |
2932 | } | ||
2658 | if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { | 2933 | if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { |
2659 | u32 err = svm->vmcb->control.exit_int_info_err; | 2934 | u32 err = svm->vmcb->control.exit_int_info_err; |
2660 | kvm_queue_exception_e(&svm->vcpu, vector, err); | 2935 | kvm_queue_exception_e(&svm->vcpu, vector, err); |
@@ -2875,24 +3150,24 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
2875 | } | 3150 | } |
2876 | 3151 | ||
2877 | static const struct trace_print_flags svm_exit_reasons_str[] = { | 3152 | static const struct trace_print_flags svm_exit_reasons_str[] = { |
2878 | { SVM_EXIT_READ_CR0, "read_cr0" }, | 3153 | { SVM_EXIT_READ_CR0, "read_cr0" }, |
2879 | { SVM_EXIT_READ_CR3, "read_cr3" }, | 3154 | { SVM_EXIT_READ_CR3, "read_cr3" }, |
2880 | { SVM_EXIT_READ_CR4, "read_cr4" }, | 3155 | { SVM_EXIT_READ_CR4, "read_cr4" }, |
2881 | { SVM_EXIT_READ_CR8, "read_cr8" }, | 3156 | { SVM_EXIT_READ_CR8, "read_cr8" }, |
2882 | { SVM_EXIT_WRITE_CR0, "write_cr0" }, | 3157 | { SVM_EXIT_WRITE_CR0, "write_cr0" }, |
2883 | { SVM_EXIT_WRITE_CR3, "write_cr3" }, | 3158 | { SVM_EXIT_WRITE_CR3, "write_cr3" }, |
2884 | { SVM_EXIT_WRITE_CR4, "write_cr4" }, | 3159 | { SVM_EXIT_WRITE_CR4, "write_cr4" }, |
2885 | { SVM_EXIT_WRITE_CR8, "write_cr8" }, | 3160 | { SVM_EXIT_WRITE_CR8, "write_cr8" }, |
2886 | { SVM_EXIT_READ_DR0, "read_dr0" }, | 3161 | { SVM_EXIT_READ_DR0, "read_dr0" }, |
2887 | { SVM_EXIT_READ_DR1, "read_dr1" }, | 3162 | { SVM_EXIT_READ_DR1, "read_dr1" }, |
2888 | { SVM_EXIT_READ_DR2, "read_dr2" }, | 3163 | { SVM_EXIT_READ_DR2, "read_dr2" }, |
2889 | { SVM_EXIT_READ_DR3, "read_dr3" }, | 3164 | { SVM_EXIT_READ_DR3, "read_dr3" }, |
2890 | { SVM_EXIT_WRITE_DR0, "write_dr0" }, | 3165 | { SVM_EXIT_WRITE_DR0, "write_dr0" }, |
2891 | { SVM_EXIT_WRITE_DR1, "write_dr1" }, | 3166 | { SVM_EXIT_WRITE_DR1, "write_dr1" }, |
2892 | { SVM_EXIT_WRITE_DR2, "write_dr2" }, | 3167 | { SVM_EXIT_WRITE_DR2, "write_dr2" }, |
2893 | { SVM_EXIT_WRITE_DR3, "write_dr3" }, | 3168 | { SVM_EXIT_WRITE_DR3, "write_dr3" }, |
2894 | { SVM_EXIT_WRITE_DR5, "write_dr5" }, | 3169 | { SVM_EXIT_WRITE_DR5, "write_dr5" }, |
2895 | { SVM_EXIT_WRITE_DR7, "write_dr7" }, | 3170 | { SVM_EXIT_WRITE_DR7, "write_dr7" }, |
2896 | { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, | 3171 | { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, |
2897 | { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, | 3172 | { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, |
2898 | { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, | 3173 | { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, |
@@ -2941,8 +3216,10 @@ static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
2941 | { | 3216 | { |
2942 | struct vcpu_svm *svm = to_svm(vcpu); | 3217 | struct vcpu_svm *svm = to_svm(vcpu); |
2943 | 3218 | ||
2944 | update_cr0_intercept(svm); | ||
2945 | svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR; | 3219 | svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR; |
3220 | if (is_nested(svm)) | ||
3221 | svm->nested.hsave->control.intercept_exceptions |= 1 << NM_VECTOR; | ||
3222 | update_cr0_intercept(svm); | ||
2946 | } | 3223 | } |
2947 | 3224 | ||
2948 | static struct kvm_x86_ops svm_x86_ops = { | 3225 | static struct kvm_x86_ops svm_x86_ops = { |
@@ -2981,8 +3258,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2981 | .set_idt = svm_set_idt, | 3258 | .set_idt = svm_set_idt, |
2982 | .get_gdt = svm_get_gdt, | 3259 | .get_gdt = svm_get_gdt, |
2983 | .set_gdt = svm_set_gdt, | 3260 | .set_gdt = svm_set_gdt, |
2984 | .get_dr = svm_get_dr, | 3261 | .set_dr7 = svm_set_dr7, |
2985 | .set_dr = svm_set_dr, | ||
2986 | .cache_reg = svm_cache_reg, | 3262 | .cache_reg = svm_cache_reg, |
2987 | .get_rflags = svm_get_rflags, | 3263 | .get_rflags = svm_get_rflags, |
2988 | .set_rflags = svm_set_rflags, | 3264 | .set_rflags = svm_set_rflags, |
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c index eea40439066c..4ddadb1a5ffe 100644 --- a/arch/x86/kvm/timer.c +++ b/arch/x86/kvm/timer.c | |||
@@ -12,7 +12,8 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) | |||
12 | /* | 12 | /* |
13 | * There is a race window between reading and incrementing, but we do | 13 | * There is a race window between reading and incrementing, but we do |
14 | * not care about potentially loosing timer events in the !reinject | 14 | * not care about potentially loosing timer events in the !reinject |
15 | * case anyway. | 15 | * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked |
16 | * in vcpu_enter_guest. | ||
16 | */ | 17 | */ |
17 | if (ktimer->reinject || !atomic_read(&ktimer->pending)) { | 18 | if (ktimer->reinject || !atomic_read(&ktimer->pending)) { |
18 | atomic_inc(&ktimer->pending); | 19 | atomic_inc(&ktimer->pending); |
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 6ad30a29f044..a6544b8e7c0f 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -5,8 +5,6 @@ | |||
5 | 5 | ||
6 | #undef TRACE_SYSTEM | 6 | #undef TRACE_SYSTEM |
7 | #define TRACE_SYSTEM kvm | 7 | #define TRACE_SYSTEM kvm |
8 | #define TRACE_INCLUDE_PATH arch/x86/kvm | ||
9 | #define TRACE_INCLUDE_FILE trace | ||
10 | 8 | ||
11 | /* | 9 | /* |
12 | * Tracepoint for guest mode entry. | 10 | * Tracepoint for guest mode entry. |
@@ -184,8 +182,8 @@ TRACE_EVENT(kvm_apic, | |||
184 | * Tracepoint for kvm guest exit: | 182 | * Tracepoint for kvm guest exit: |
185 | */ | 183 | */ |
186 | TRACE_EVENT(kvm_exit, | 184 | TRACE_EVENT(kvm_exit, |
187 | TP_PROTO(unsigned int exit_reason, unsigned long guest_rip), | 185 | TP_PROTO(unsigned int exit_reason, struct kvm_vcpu *vcpu), |
188 | TP_ARGS(exit_reason, guest_rip), | 186 | TP_ARGS(exit_reason, vcpu), |
189 | 187 | ||
190 | TP_STRUCT__entry( | 188 | TP_STRUCT__entry( |
191 | __field( unsigned int, exit_reason ) | 189 | __field( unsigned int, exit_reason ) |
@@ -194,7 +192,7 @@ TRACE_EVENT(kvm_exit, | |||
194 | 192 | ||
195 | TP_fast_assign( | 193 | TP_fast_assign( |
196 | __entry->exit_reason = exit_reason; | 194 | __entry->exit_reason = exit_reason; |
197 | __entry->guest_rip = guest_rip; | 195 | __entry->guest_rip = kvm_rip_read(vcpu); |
198 | ), | 196 | ), |
199 | 197 | ||
200 | TP_printk("reason %s rip 0x%lx", | 198 | TP_printk("reason %s rip 0x%lx", |
@@ -221,6 +219,38 @@ TRACE_EVENT(kvm_inj_virq, | |||
221 | TP_printk("irq %u", __entry->irq) | 219 | TP_printk("irq %u", __entry->irq) |
222 | ); | 220 | ); |
223 | 221 | ||
222 | #define EXS(x) { x##_VECTOR, "#" #x } | ||
223 | |||
224 | #define kvm_trace_sym_exc \ | ||
225 | EXS(DE), EXS(DB), EXS(BP), EXS(OF), EXS(BR), EXS(UD), EXS(NM), \ | ||
226 | EXS(DF), EXS(TS), EXS(NP), EXS(SS), EXS(GP), EXS(PF), \ | ||
227 | EXS(MF), EXS(MC) | ||
228 | |||
229 | /* | ||
230 | * Tracepoint for kvm interrupt injection: | ||
231 | */ | ||
232 | TRACE_EVENT(kvm_inj_exception, | ||
233 | TP_PROTO(unsigned exception, bool has_error, unsigned error_code), | ||
234 | TP_ARGS(exception, has_error, error_code), | ||
235 | |||
236 | TP_STRUCT__entry( | ||
237 | __field( u8, exception ) | ||
238 | __field( u8, has_error ) | ||
239 | __field( u32, error_code ) | ||
240 | ), | ||
241 | |||
242 | TP_fast_assign( | ||
243 | __entry->exception = exception; | ||
244 | __entry->has_error = has_error; | ||
245 | __entry->error_code = error_code; | ||
246 | ), | ||
247 | |||
248 | TP_printk("%s (0x%x)", | ||
249 | __print_symbolic(__entry->exception, kvm_trace_sym_exc), | ||
250 | /* FIXME: don't print error_code if not present */ | ||
251 | __entry->has_error ? __entry->error_code : 0) | ||
252 | ); | ||
253 | |||
224 | /* | 254 | /* |
225 | * Tracepoint for page fault. | 255 | * Tracepoint for page fault. |
226 | */ | 256 | */ |
@@ -413,12 +443,34 @@ TRACE_EVENT(kvm_nested_vmrun, | |||
413 | ), | 443 | ), |
414 | 444 | ||
415 | TP_printk("rip: 0x%016llx vmcb: 0x%016llx nrip: 0x%016llx int_ctl: 0x%08x " | 445 | TP_printk("rip: 0x%016llx vmcb: 0x%016llx nrip: 0x%016llx int_ctl: 0x%08x " |
416 | "event_inj: 0x%08x npt: %s\n", | 446 | "event_inj: 0x%08x npt: %s", |
417 | __entry->rip, __entry->vmcb, __entry->nested_rip, | 447 | __entry->rip, __entry->vmcb, __entry->nested_rip, |
418 | __entry->int_ctl, __entry->event_inj, | 448 | __entry->int_ctl, __entry->event_inj, |
419 | __entry->npt ? "on" : "off") | 449 | __entry->npt ? "on" : "off") |
420 | ); | 450 | ); |
421 | 451 | ||
452 | TRACE_EVENT(kvm_nested_intercepts, | ||
453 | TP_PROTO(__u16 cr_read, __u16 cr_write, __u32 exceptions, __u64 intercept), | ||
454 | TP_ARGS(cr_read, cr_write, exceptions, intercept), | ||
455 | |||
456 | TP_STRUCT__entry( | ||
457 | __field( __u16, cr_read ) | ||
458 | __field( __u16, cr_write ) | ||
459 | __field( __u32, exceptions ) | ||
460 | __field( __u64, intercept ) | ||
461 | ), | ||
462 | |||
463 | TP_fast_assign( | ||
464 | __entry->cr_read = cr_read; | ||
465 | __entry->cr_write = cr_write; | ||
466 | __entry->exceptions = exceptions; | ||
467 | __entry->intercept = intercept; | ||
468 | ), | ||
469 | |||
470 | TP_printk("cr_read: %04x cr_write: %04x excp: %08x intercept: %016llx", | ||
471 | __entry->cr_read, __entry->cr_write, __entry->exceptions, | ||
472 | __entry->intercept) | ||
473 | ); | ||
422 | /* | 474 | /* |
423 | * Tracepoint for #VMEXIT while nested | 475 | * Tracepoint for #VMEXIT while nested |
424 | */ | 476 | */ |
@@ -447,7 +499,7 @@ TRACE_EVENT(kvm_nested_vmexit, | |||
447 | __entry->exit_int_info_err = exit_int_info_err; | 499 | __entry->exit_int_info_err = exit_int_info_err; |
448 | ), | 500 | ), |
449 | TP_printk("rip: 0x%016llx reason: %s ext_inf1: 0x%016llx " | 501 | TP_printk("rip: 0x%016llx reason: %s ext_inf1: 0x%016llx " |
450 | "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n", | 502 | "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x", |
451 | __entry->rip, | 503 | __entry->rip, |
452 | ftrace_print_symbols_seq(p, __entry->exit_code, | 504 | ftrace_print_symbols_seq(p, __entry->exit_code, |
453 | kvm_x86_ops->exit_reasons_str), | 505 | kvm_x86_ops->exit_reasons_str), |
@@ -482,7 +534,7 @@ TRACE_EVENT(kvm_nested_vmexit_inject, | |||
482 | ), | 534 | ), |
483 | 535 | ||
484 | TP_printk("reason: %s ext_inf1: 0x%016llx " | 536 | TP_printk("reason: %s ext_inf1: 0x%016llx " |
485 | "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x\n", | 537 | "ext_inf2: 0x%016llx ext_int: 0x%08x ext_int_err: 0x%08x", |
486 | ftrace_print_symbols_seq(p, __entry->exit_code, | 538 | ftrace_print_symbols_seq(p, __entry->exit_code, |
487 | kvm_x86_ops->exit_reasons_str), | 539 | kvm_x86_ops->exit_reasons_str), |
488 | __entry->exit_info1, __entry->exit_info2, | 540 | __entry->exit_info1, __entry->exit_info2, |
@@ -504,7 +556,7 @@ TRACE_EVENT(kvm_nested_intr_vmexit, | |||
504 | __entry->rip = rip | 556 | __entry->rip = rip |
505 | ), | 557 | ), |
506 | 558 | ||
507 | TP_printk("rip: 0x%016llx\n", __entry->rip) | 559 | TP_printk("rip: 0x%016llx", __entry->rip) |
508 | ); | 560 | ); |
509 | 561 | ||
510 | /* | 562 | /* |
@@ -526,7 +578,7 @@ TRACE_EVENT(kvm_invlpga, | |||
526 | __entry->address = address; | 578 | __entry->address = address; |
527 | ), | 579 | ), |
528 | 580 | ||
529 | TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx\n", | 581 | TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx", |
530 | __entry->rip, __entry->asid, __entry->address) | 582 | __entry->rip, __entry->asid, __entry->address) |
531 | ); | 583 | ); |
532 | 584 | ||
@@ -547,11 +599,102 @@ TRACE_EVENT(kvm_skinit, | |||
547 | __entry->slb = slb; | 599 | __entry->slb = slb; |
548 | ), | 600 | ), |
549 | 601 | ||
550 | TP_printk("rip: 0x%016llx slb: 0x%08x\n", | 602 | TP_printk("rip: 0x%016llx slb: 0x%08x", |
551 | __entry->rip, __entry->slb) | 603 | __entry->rip, __entry->slb) |
552 | ); | 604 | ); |
553 | 605 | ||
606 | #define __print_insn(insn, ilen) ({ \ | ||
607 | int i; \ | ||
608 | const char *ret = p->buffer + p->len; \ | ||
609 | \ | ||
610 | for (i = 0; i < ilen; ++i) \ | ||
611 | trace_seq_printf(p, " %02x", insn[i]); \ | ||
612 | trace_seq_printf(p, "%c", 0); \ | ||
613 | ret; \ | ||
614 | }) | ||
615 | |||
616 | #define KVM_EMUL_INSN_F_CR0_PE (1 << 0) | ||
617 | #define KVM_EMUL_INSN_F_EFL_VM (1 << 1) | ||
618 | #define KVM_EMUL_INSN_F_CS_D (1 << 2) | ||
619 | #define KVM_EMUL_INSN_F_CS_L (1 << 3) | ||
620 | |||
621 | #define kvm_trace_symbol_emul_flags \ | ||
622 | { 0, "real" }, \ | ||
623 | { KVM_EMUL_INSN_F_CR0_PE \ | ||
624 | | KVM_EMUL_INSN_F_EFL_VM, "vm16" }, \ | ||
625 | { KVM_EMUL_INSN_F_CR0_PE, "prot16" }, \ | ||
626 | { KVM_EMUL_INSN_F_CR0_PE \ | ||
627 | | KVM_EMUL_INSN_F_CS_D, "prot32" }, \ | ||
628 | { KVM_EMUL_INSN_F_CR0_PE \ | ||
629 | | KVM_EMUL_INSN_F_CS_L, "prot64" } | ||
630 | |||
631 | #define kei_decode_mode(mode) ({ \ | ||
632 | u8 flags = 0xff; \ | ||
633 | switch (mode) { \ | ||
634 | case X86EMUL_MODE_REAL: \ | ||
635 | flags = 0; \ | ||
636 | break; \ | ||
637 | case X86EMUL_MODE_VM86: \ | ||
638 | flags = KVM_EMUL_INSN_F_EFL_VM; \ | ||
639 | break; \ | ||
640 | case X86EMUL_MODE_PROT16: \ | ||
641 | flags = KVM_EMUL_INSN_F_CR0_PE; \ | ||
642 | break; \ | ||
643 | case X86EMUL_MODE_PROT32: \ | ||
644 | flags = KVM_EMUL_INSN_F_CR0_PE \ | ||
645 | | KVM_EMUL_INSN_F_CS_D; \ | ||
646 | break; \ | ||
647 | case X86EMUL_MODE_PROT64: \ | ||
648 | flags = KVM_EMUL_INSN_F_CR0_PE \ | ||
649 | | KVM_EMUL_INSN_F_CS_L; \ | ||
650 | break; \ | ||
651 | } \ | ||
652 | flags; \ | ||
653 | }) | ||
654 | |||
655 | TRACE_EVENT(kvm_emulate_insn, | ||
656 | TP_PROTO(struct kvm_vcpu *vcpu, __u8 failed), | ||
657 | TP_ARGS(vcpu, failed), | ||
658 | |||
659 | TP_STRUCT__entry( | ||
660 | __field( __u64, rip ) | ||
661 | __field( __u32, csbase ) | ||
662 | __field( __u8, len ) | ||
663 | __array( __u8, insn, 15 ) | ||
664 | __field( __u8, flags ) | ||
665 | __field( __u8, failed ) | ||
666 | ), | ||
667 | |||
668 | TP_fast_assign( | ||
669 | __entry->rip = vcpu->arch.emulate_ctxt.decode.fetch.start; | ||
670 | __entry->csbase = kvm_x86_ops->get_segment_base(vcpu, VCPU_SREG_CS); | ||
671 | __entry->len = vcpu->arch.emulate_ctxt.decode.eip | ||
672 | - vcpu->arch.emulate_ctxt.decode.fetch.start; | ||
673 | memcpy(__entry->insn, | ||
674 | vcpu->arch.emulate_ctxt.decode.fetch.data, | ||
675 | 15); | ||
676 | __entry->flags = kei_decode_mode(vcpu->arch.emulate_ctxt.mode); | ||
677 | __entry->failed = failed; | ||
678 | ), | ||
679 | |||
680 | TP_printk("%x:%llx:%s (%s)%s", | ||
681 | __entry->csbase, __entry->rip, | ||
682 | __print_insn(__entry->insn, __entry->len), | ||
683 | __print_symbolic(__entry->flags, | ||
684 | kvm_trace_symbol_emul_flags), | ||
685 | __entry->failed ? " failed" : "" | ||
686 | ) | ||
687 | ); | ||
688 | |||
689 | #define trace_kvm_emulate_insn_start(vcpu) trace_kvm_emulate_insn(vcpu, 0) | ||
690 | #define trace_kvm_emulate_insn_failed(vcpu) trace_kvm_emulate_insn(vcpu, 1) | ||
691 | |||
554 | #endif /* _TRACE_KVM_H */ | 692 | #endif /* _TRACE_KVM_H */ |
555 | 693 | ||
694 | #undef TRACE_INCLUDE_PATH | ||
695 | #define TRACE_INCLUDE_PATH arch/x86/kvm | ||
696 | #undef TRACE_INCLUDE_FILE | ||
697 | #define TRACE_INCLUDE_FILE trace | ||
698 | |||
556 | /* This part must be outside protection */ | 699 | /* This part must be outside protection */ |
557 | #include <trace/define_trace.h> | 700 | #include <trace/define_trace.h> |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 82be6dac3d25..0b896ac7e4bb 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -77,6 +77,8 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO); | |||
77 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) | 77 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) |
78 | #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) | 78 | #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE) |
79 | 79 | ||
80 | #define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM)) | ||
81 | |||
80 | /* | 82 | /* |
81 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: | 83 | * These 2 parameters are used to config the controls for Pause-Loop Exiting: |
82 | * ple_gap: upper bound on the amount of time between two successive | 84 | * ple_gap: upper bound on the amount of time between two successive |
@@ -131,7 +133,7 @@ struct vcpu_vmx { | |||
131 | } host_state; | 133 | } host_state; |
132 | struct { | 134 | struct { |
133 | int vm86_active; | 135 | int vm86_active; |
134 | u8 save_iopl; | 136 | ulong save_rflags; |
135 | struct kvm_save_segment { | 137 | struct kvm_save_segment { |
136 | u16 selector; | 138 | u16 selector; |
137 | unsigned long base; | 139 | unsigned long base; |
@@ -232,56 +234,56 @@ static const u32 vmx_msr_index[] = { | |||
232 | }; | 234 | }; |
233 | #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) | 235 | #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) |
234 | 236 | ||
235 | static inline int is_page_fault(u32 intr_info) | 237 | static inline bool is_page_fault(u32 intr_info) |
236 | { | 238 | { |
237 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | 239 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | |
238 | INTR_INFO_VALID_MASK)) == | 240 | INTR_INFO_VALID_MASK)) == |
239 | (INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK); | 241 | (INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK); |
240 | } | 242 | } |
241 | 243 | ||
242 | static inline int is_no_device(u32 intr_info) | 244 | static inline bool is_no_device(u32 intr_info) |
243 | { | 245 | { |
244 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | 246 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | |
245 | INTR_INFO_VALID_MASK)) == | 247 | INTR_INFO_VALID_MASK)) == |
246 | (INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK); | 248 | (INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK); |
247 | } | 249 | } |
248 | 250 | ||
249 | static inline int is_invalid_opcode(u32 intr_info) | 251 | static inline bool is_invalid_opcode(u32 intr_info) |
250 | { | 252 | { |
251 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | 253 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | |
252 | INTR_INFO_VALID_MASK)) == | 254 | INTR_INFO_VALID_MASK)) == |
253 | (INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK); | 255 | (INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK); |
254 | } | 256 | } |
255 | 257 | ||
256 | static inline int is_external_interrupt(u32 intr_info) | 258 | static inline bool is_external_interrupt(u32 intr_info) |
257 | { | 259 | { |
258 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | 260 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) |
259 | == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); | 261 | == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); |
260 | } | 262 | } |
261 | 263 | ||
262 | static inline int is_machine_check(u32 intr_info) | 264 | static inline bool is_machine_check(u32 intr_info) |
263 | { | 265 | { |
264 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | | 266 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | |
265 | INTR_INFO_VALID_MASK)) == | 267 | INTR_INFO_VALID_MASK)) == |
266 | (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); | 268 | (INTR_TYPE_HARD_EXCEPTION | MC_VECTOR | INTR_INFO_VALID_MASK); |
267 | } | 269 | } |
268 | 270 | ||
269 | static inline int cpu_has_vmx_msr_bitmap(void) | 271 | static inline bool cpu_has_vmx_msr_bitmap(void) |
270 | { | 272 | { |
271 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS; | 273 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS; |
272 | } | 274 | } |
273 | 275 | ||
274 | static inline int cpu_has_vmx_tpr_shadow(void) | 276 | static inline bool cpu_has_vmx_tpr_shadow(void) |
275 | { | 277 | { |
276 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW; | 278 | return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW; |
277 | } | 279 | } |
278 | 280 | ||
279 | static inline int vm_need_tpr_shadow(struct kvm *kvm) | 281 | static inline bool vm_need_tpr_shadow(struct kvm *kvm) |
280 | { | 282 | { |
281 | return (cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm)); | 283 | return (cpu_has_vmx_tpr_shadow()) && (irqchip_in_kernel(kvm)); |
282 | } | 284 | } |
283 | 285 | ||
284 | static inline int cpu_has_secondary_exec_ctrls(void) | 286 | static inline bool cpu_has_secondary_exec_ctrls(void) |
285 | { | 287 | { |
286 | return vmcs_config.cpu_based_exec_ctrl & | 288 | return vmcs_config.cpu_based_exec_ctrl & |
287 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; | 289 | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; |
@@ -301,80 +303,80 @@ static inline bool cpu_has_vmx_flexpriority(void) | |||
301 | 303 | ||
302 | static inline bool cpu_has_vmx_ept_execute_only(void) | 304 | static inline bool cpu_has_vmx_ept_execute_only(void) |
303 | { | 305 | { |
304 | return !!(vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT); | 306 | return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT; |
305 | } | 307 | } |
306 | 308 | ||
307 | static inline bool cpu_has_vmx_eptp_uncacheable(void) | 309 | static inline bool cpu_has_vmx_eptp_uncacheable(void) |
308 | { | 310 | { |
309 | return !!(vmx_capability.ept & VMX_EPTP_UC_BIT); | 311 | return vmx_capability.ept & VMX_EPTP_UC_BIT; |
310 | } | 312 | } |
311 | 313 | ||
312 | static inline bool cpu_has_vmx_eptp_writeback(void) | 314 | static inline bool cpu_has_vmx_eptp_writeback(void) |
313 | { | 315 | { |
314 | return !!(vmx_capability.ept & VMX_EPTP_WB_BIT); | 316 | return vmx_capability.ept & VMX_EPTP_WB_BIT; |
315 | } | 317 | } |
316 | 318 | ||
317 | static inline bool cpu_has_vmx_ept_2m_page(void) | 319 | static inline bool cpu_has_vmx_ept_2m_page(void) |
318 | { | 320 | { |
319 | return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT); | 321 | return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT; |
320 | } | 322 | } |
321 | 323 | ||
322 | static inline bool cpu_has_vmx_ept_1g_page(void) | 324 | static inline bool cpu_has_vmx_ept_1g_page(void) |
323 | { | 325 | { |
324 | return !!(vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT); | 326 | return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT; |
325 | } | 327 | } |
326 | 328 | ||
327 | static inline int cpu_has_vmx_invept_individual_addr(void) | 329 | static inline bool cpu_has_vmx_invept_individual_addr(void) |
328 | { | 330 | { |
329 | return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); | 331 | return vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT; |
330 | } | 332 | } |
331 | 333 | ||
332 | static inline int cpu_has_vmx_invept_context(void) | 334 | static inline bool cpu_has_vmx_invept_context(void) |
333 | { | 335 | { |
334 | return !!(vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT); | 336 | return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT; |
335 | } | 337 | } |
336 | 338 | ||
337 | static inline int cpu_has_vmx_invept_global(void) | 339 | static inline bool cpu_has_vmx_invept_global(void) |
338 | { | 340 | { |
339 | return !!(vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT); | 341 | return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT; |
340 | } | 342 | } |
341 | 343 | ||
342 | static inline int cpu_has_vmx_ept(void) | 344 | static inline bool cpu_has_vmx_ept(void) |
343 | { | 345 | { |
344 | return vmcs_config.cpu_based_2nd_exec_ctrl & | 346 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
345 | SECONDARY_EXEC_ENABLE_EPT; | 347 | SECONDARY_EXEC_ENABLE_EPT; |
346 | } | 348 | } |
347 | 349 | ||
348 | static inline int cpu_has_vmx_unrestricted_guest(void) | 350 | static inline bool cpu_has_vmx_unrestricted_guest(void) |
349 | { | 351 | { |
350 | return vmcs_config.cpu_based_2nd_exec_ctrl & | 352 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
351 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | 353 | SECONDARY_EXEC_UNRESTRICTED_GUEST; |
352 | } | 354 | } |
353 | 355 | ||
354 | static inline int cpu_has_vmx_ple(void) | 356 | static inline bool cpu_has_vmx_ple(void) |
355 | { | 357 | { |
356 | return vmcs_config.cpu_based_2nd_exec_ctrl & | 358 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
357 | SECONDARY_EXEC_PAUSE_LOOP_EXITING; | 359 | SECONDARY_EXEC_PAUSE_LOOP_EXITING; |
358 | } | 360 | } |
359 | 361 | ||
360 | static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) | 362 | static inline bool vm_need_virtualize_apic_accesses(struct kvm *kvm) |
361 | { | 363 | { |
362 | return flexpriority_enabled && irqchip_in_kernel(kvm); | 364 | return flexpriority_enabled && irqchip_in_kernel(kvm); |
363 | } | 365 | } |
364 | 366 | ||
365 | static inline int cpu_has_vmx_vpid(void) | 367 | static inline bool cpu_has_vmx_vpid(void) |
366 | { | 368 | { |
367 | return vmcs_config.cpu_based_2nd_exec_ctrl & | 369 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
368 | SECONDARY_EXEC_ENABLE_VPID; | 370 | SECONDARY_EXEC_ENABLE_VPID; |
369 | } | 371 | } |
370 | 372 | ||
371 | static inline int cpu_has_vmx_rdtscp(void) | 373 | static inline bool cpu_has_vmx_rdtscp(void) |
372 | { | 374 | { |
373 | return vmcs_config.cpu_based_2nd_exec_ctrl & | 375 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
374 | SECONDARY_EXEC_RDTSCP; | 376 | SECONDARY_EXEC_RDTSCP; |
375 | } | 377 | } |
376 | 378 | ||
377 | static inline int cpu_has_virtual_nmis(void) | 379 | static inline bool cpu_has_virtual_nmis(void) |
378 | { | 380 | { |
379 | return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS; | 381 | return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS; |
380 | } | 382 | } |
@@ -598,11 +600,11 @@ static void reload_tss(void) | |||
598 | /* | 600 | /* |
599 | * VT restores TR but not its size. Useless. | 601 | * VT restores TR but not its size. Useless. |
600 | */ | 602 | */ |
601 | struct descriptor_table gdt; | 603 | struct desc_ptr gdt; |
602 | struct desc_struct *descs; | 604 | struct desc_struct *descs; |
603 | 605 | ||
604 | kvm_get_gdt(&gdt); | 606 | native_store_gdt(&gdt); |
605 | descs = (void *)gdt.base; | 607 | descs = (void *)gdt.address; |
606 | descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ | 608 | descs[GDT_ENTRY_TSS].type = 9; /* available TSS */ |
607 | load_TR_desc(); | 609 | load_TR_desc(); |
608 | } | 610 | } |
@@ -632,6 +634,43 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) | |||
632 | return true; | 634 | return true; |
633 | } | 635 | } |
634 | 636 | ||
637 | static unsigned long segment_base(u16 selector) | ||
638 | { | ||
639 | struct desc_ptr gdt; | ||
640 | struct desc_struct *d; | ||
641 | unsigned long table_base; | ||
642 | unsigned long v; | ||
643 | |||
644 | if (!(selector & ~3)) | ||
645 | return 0; | ||
646 | |||
647 | native_store_gdt(&gdt); | ||
648 | table_base = gdt.address; | ||
649 | |||
650 | if (selector & 4) { /* from ldt */ | ||
651 | u16 ldt_selector = kvm_read_ldt(); | ||
652 | |||
653 | if (!(ldt_selector & ~3)) | ||
654 | return 0; | ||
655 | |||
656 | table_base = segment_base(ldt_selector); | ||
657 | } | ||
658 | d = (struct desc_struct *)(table_base + (selector & ~7)); | ||
659 | v = get_desc_base(d); | ||
660 | #ifdef CONFIG_X86_64 | ||
661 | if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) | ||
662 | v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; | ||
663 | #endif | ||
664 | return v; | ||
665 | } | ||
666 | |||
667 | static inline unsigned long kvm_read_tr_base(void) | ||
668 | { | ||
669 | u16 tr; | ||
670 | asm("str %0" : "=g"(tr)); | ||
671 | return segment_base(tr); | ||
672 | } | ||
673 | |||
635 | static void vmx_save_host_state(struct kvm_vcpu *vcpu) | 674 | static void vmx_save_host_state(struct kvm_vcpu *vcpu) |
636 | { | 675 | { |
637 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 676 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
@@ -756,7 +795,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
756 | } | 795 | } |
757 | 796 | ||
758 | if (vcpu->cpu != cpu) { | 797 | if (vcpu->cpu != cpu) { |
759 | struct descriptor_table dt; | 798 | struct desc_ptr dt; |
760 | unsigned long sysenter_esp; | 799 | unsigned long sysenter_esp; |
761 | 800 | ||
762 | vcpu->cpu = cpu; | 801 | vcpu->cpu = cpu; |
@@ -765,8 +804,8 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
765 | * processors. | 804 | * processors. |
766 | */ | 805 | */ |
767 | vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ | 806 | vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ |
768 | kvm_get_gdt(&dt); | 807 | native_store_gdt(&dt); |
769 | vmcs_writel(HOST_GDTR_BASE, dt.base); /* 22.2.4 */ | 808 | vmcs_writel(HOST_GDTR_BASE, dt.address); /* 22.2.4 */ |
770 | 809 | ||
771 | rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); | 810 | rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); |
772 | vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ | 811 | vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ |
@@ -818,18 +857,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
818 | 857 | ||
819 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | 858 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) |
820 | { | 859 | { |
821 | unsigned long rflags; | 860 | unsigned long rflags, save_rflags; |
822 | 861 | ||
823 | rflags = vmcs_readl(GUEST_RFLAGS); | 862 | rflags = vmcs_readl(GUEST_RFLAGS); |
824 | if (to_vmx(vcpu)->rmode.vm86_active) | 863 | if (to_vmx(vcpu)->rmode.vm86_active) { |
825 | rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | 864 | rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
865 | save_rflags = to_vmx(vcpu)->rmode.save_rflags; | ||
866 | rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; | ||
867 | } | ||
826 | return rflags; | 868 | return rflags; |
827 | } | 869 | } |
828 | 870 | ||
829 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 871 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
830 | { | 872 | { |
831 | if (to_vmx(vcpu)->rmode.vm86_active) | 873 | if (to_vmx(vcpu)->rmode.vm86_active) { |
874 | to_vmx(vcpu)->rmode.save_rflags = rflags; | ||
832 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 875 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
876 | } | ||
833 | vmcs_writel(GUEST_RFLAGS, rflags); | 877 | vmcs_writel(GUEST_RFLAGS, rflags); |
834 | } | 878 | } |
835 | 879 | ||
@@ -839,9 +883,9 @@ static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
839 | int ret = 0; | 883 | int ret = 0; |
840 | 884 | ||
841 | if (interruptibility & GUEST_INTR_STATE_STI) | 885 | if (interruptibility & GUEST_INTR_STATE_STI) |
842 | ret |= X86_SHADOW_INT_STI; | 886 | ret |= KVM_X86_SHADOW_INT_STI; |
843 | if (interruptibility & GUEST_INTR_STATE_MOV_SS) | 887 | if (interruptibility & GUEST_INTR_STATE_MOV_SS) |
844 | ret |= X86_SHADOW_INT_MOV_SS; | 888 | ret |= KVM_X86_SHADOW_INT_MOV_SS; |
845 | 889 | ||
846 | return ret & mask; | 890 | return ret & mask; |
847 | } | 891 | } |
@@ -853,9 +897,9 @@ static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask) | |||
853 | 897 | ||
854 | interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); | 898 | interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS); |
855 | 899 | ||
856 | if (mask & X86_SHADOW_INT_MOV_SS) | 900 | if (mask & KVM_X86_SHADOW_INT_MOV_SS) |
857 | interruptibility |= GUEST_INTR_STATE_MOV_SS; | 901 | interruptibility |= GUEST_INTR_STATE_MOV_SS; |
858 | if (mask & X86_SHADOW_INT_STI) | 902 | else if (mask & KVM_X86_SHADOW_INT_STI) |
859 | interruptibility |= GUEST_INTR_STATE_STI; | 903 | interruptibility |= GUEST_INTR_STATE_STI; |
860 | 904 | ||
861 | if ((interruptibility != interruptibility_old)) | 905 | if ((interruptibility != interruptibility_old)) |
@@ -1483,8 +1527,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu) | |||
1483 | vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); | 1527 | vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); |
1484 | 1528 | ||
1485 | flags = vmcs_readl(GUEST_RFLAGS); | 1529 | flags = vmcs_readl(GUEST_RFLAGS); |
1486 | flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | 1530 | flags &= RMODE_GUEST_OWNED_EFLAGS_BITS; |
1487 | flags |= (vmx->rmode.save_iopl << IOPL_SHIFT); | 1531 | flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS; |
1488 | vmcs_writel(GUEST_RFLAGS, flags); | 1532 | vmcs_writel(GUEST_RFLAGS, flags); |
1489 | 1533 | ||
1490 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | | 1534 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | |
@@ -1557,8 +1601,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) | |||
1557 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); | 1601 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); |
1558 | 1602 | ||
1559 | flags = vmcs_readl(GUEST_RFLAGS); | 1603 | flags = vmcs_readl(GUEST_RFLAGS); |
1560 | vmx->rmode.save_iopl | 1604 | vmx->rmode.save_rflags = flags; |
1561 | = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | ||
1562 | 1605 | ||
1563 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 1606 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
1564 | 1607 | ||
@@ -1928,28 +1971,28 @@ static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) | |||
1928 | *l = (ar >> 13) & 1; | 1971 | *l = (ar >> 13) & 1; |
1929 | } | 1972 | } |
1930 | 1973 | ||
1931 | static void vmx_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1974 | static void vmx_get_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
1932 | { | 1975 | { |
1933 | dt->limit = vmcs_read32(GUEST_IDTR_LIMIT); | 1976 | dt->size = vmcs_read32(GUEST_IDTR_LIMIT); |
1934 | dt->base = vmcs_readl(GUEST_IDTR_BASE); | 1977 | dt->address = vmcs_readl(GUEST_IDTR_BASE); |
1935 | } | 1978 | } |
1936 | 1979 | ||
1937 | static void vmx_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1980 | static void vmx_set_idt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
1938 | { | 1981 | { |
1939 | vmcs_write32(GUEST_IDTR_LIMIT, dt->limit); | 1982 | vmcs_write32(GUEST_IDTR_LIMIT, dt->size); |
1940 | vmcs_writel(GUEST_IDTR_BASE, dt->base); | 1983 | vmcs_writel(GUEST_IDTR_BASE, dt->address); |
1941 | } | 1984 | } |
1942 | 1985 | ||
1943 | static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1986 | static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
1944 | { | 1987 | { |
1945 | dt->limit = vmcs_read32(GUEST_GDTR_LIMIT); | 1988 | dt->size = vmcs_read32(GUEST_GDTR_LIMIT); |
1946 | dt->base = vmcs_readl(GUEST_GDTR_BASE); | 1989 | dt->address = vmcs_readl(GUEST_GDTR_BASE); |
1947 | } | 1990 | } |
1948 | 1991 | ||
1949 | static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 1992 | static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt) |
1950 | { | 1993 | { |
1951 | vmcs_write32(GUEST_GDTR_LIMIT, dt->limit); | 1994 | vmcs_write32(GUEST_GDTR_LIMIT, dt->size); |
1952 | vmcs_writel(GUEST_GDTR_BASE, dt->base); | 1995 | vmcs_writel(GUEST_GDTR_BASE, dt->address); |
1953 | } | 1996 | } |
1954 | 1997 | ||
1955 | static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg) | 1998 | static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg) |
@@ -2328,7 +2371,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
2328 | u32 junk; | 2371 | u32 junk; |
2329 | u64 host_pat, tsc_this, tsc_base; | 2372 | u64 host_pat, tsc_this, tsc_base; |
2330 | unsigned long a; | 2373 | unsigned long a; |
2331 | struct descriptor_table dt; | 2374 | struct desc_ptr dt; |
2332 | int i; | 2375 | int i; |
2333 | unsigned long kvm_vmx_return; | 2376 | unsigned long kvm_vmx_return; |
2334 | u32 exec_control; | 2377 | u32 exec_control; |
@@ -2409,8 +2452,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
2409 | 2452 | ||
2410 | vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ | 2453 | vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ |
2411 | 2454 | ||
2412 | kvm_get_idt(&dt); | 2455 | native_store_idt(&dt); |
2413 | vmcs_writel(HOST_IDTR_BASE, dt.base); /* 22.2.4 */ | 2456 | vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ |
2414 | 2457 | ||
2415 | asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); | 2458 | asm("mov $.Lkvm_vmx_return, %0" : "=r"(kvm_vmx_return)); |
2416 | vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ | 2459 | vmcs_writel(HOST_RIP, kvm_vmx_return); /* 22.2.5 */ |
@@ -2942,22 +2985,20 @@ static int handle_io(struct kvm_vcpu *vcpu) | |||
2942 | int size, in, string; | 2985 | int size, in, string; |
2943 | unsigned port; | 2986 | unsigned port; |
2944 | 2987 | ||
2945 | ++vcpu->stat.io_exits; | ||
2946 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 2988 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
2947 | string = (exit_qualification & 16) != 0; | 2989 | string = (exit_qualification & 16) != 0; |
2990 | in = (exit_qualification & 8) != 0; | ||
2948 | 2991 | ||
2949 | if (string) { | 2992 | ++vcpu->stat.io_exits; |
2950 | if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO) | ||
2951 | return 0; | ||
2952 | return 1; | ||
2953 | } | ||
2954 | 2993 | ||
2955 | size = (exit_qualification & 7) + 1; | 2994 | if (string || in) |
2956 | in = (exit_qualification & 8) != 0; | 2995 | return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); |
2957 | port = exit_qualification >> 16; | ||
2958 | 2996 | ||
2997 | port = exit_qualification >> 16; | ||
2998 | size = (exit_qualification & 7) + 1; | ||
2959 | skip_emulated_instruction(vcpu); | 2999 | skip_emulated_instruction(vcpu); |
2960 | return kvm_emulate_pio(vcpu, in, size, port); | 3000 | |
3001 | return kvm_fast_pio_out(vcpu, size, port); | ||
2961 | } | 3002 | } |
2962 | 3003 | ||
2963 | static void | 3004 | static void |
@@ -3048,19 +3089,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3048 | return 0; | 3089 | return 0; |
3049 | } | 3090 | } |
3050 | 3091 | ||
3051 | static int check_dr_alias(struct kvm_vcpu *vcpu) | ||
3052 | { | ||
3053 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
3054 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
3055 | return -1; | ||
3056 | } | ||
3057 | return 0; | ||
3058 | } | ||
3059 | |||
3060 | static int handle_dr(struct kvm_vcpu *vcpu) | 3092 | static int handle_dr(struct kvm_vcpu *vcpu) |
3061 | { | 3093 | { |
3062 | unsigned long exit_qualification; | 3094 | unsigned long exit_qualification; |
3063 | unsigned long val; | ||
3064 | int dr, reg; | 3095 | int dr, reg; |
3065 | 3096 | ||
3066 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ | 3097 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ |
@@ -3095,67 +3126,20 @@ static int handle_dr(struct kvm_vcpu *vcpu) | |||
3095 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; | 3126 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; |
3096 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); | 3127 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); |
3097 | if (exit_qualification & TYPE_MOV_FROM_DR) { | 3128 | if (exit_qualification & TYPE_MOV_FROM_DR) { |
3098 | switch (dr) { | 3129 | unsigned long val; |
3099 | case 0 ... 3: | 3130 | if (!kvm_get_dr(vcpu, dr, &val)) |
3100 | val = vcpu->arch.db[dr]; | 3131 | kvm_register_write(vcpu, reg, val); |
3101 | break; | 3132 | } else |
3102 | case 4: | 3133 | kvm_set_dr(vcpu, dr, vcpu->arch.regs[reg]); |
3103 | if (check_dr_alias(vcpu) < 0) | ||
3104 | return 1; | ||
3105 | /* fall through */ | ||
3106 | case 6: | ||
3107 | val = vcpu->arch.dr6; | ||
3108 | break; | ||
3109 | case 5: | ||
3110 | if (check_dr_alias(vcpu) < 0) | ||
3111 | return 1; | ||
3112 | /* fall through */ | ||
3113 | default: /* 7 */ | ||
3114 | val = vcpu->arch.dr7; | ||
3115 | break; | ||
3116 | } | ||
3117 | kvm_register_write(vcpu, reg, val); | ||
3118 | } else { | ||
3119 | val = vcpu->arch.regs[reg]; | ||
3120 | switch (dr) { | ||
3121 | case 0 ... 3: | ||
3122 | vcpu->arch.db[dr] = val; | ||
3123 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | ||
3124 | vcpu->arch.eff_db[dr] = val; | ||
3125 | break; | ||
3126 | case 4: | ||
3127 | if (check_dr_alias(vcpu) < 0) | ||
3128 | return 1; | ||
3129 | /* fall through */ | ||
3130 | case 6: | ||
3131 | if (val & 0xffffffff00000000ULL) { | ||
3132 | kvm_inject_gp(vcpu, 0); | ||
3133 | return 1; | ||
3134 | } | ||
3135 | vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; | ||
3136 | break; | ||
3137 | case 5: | ||
3138 | if (check_dr_alias(vcpu) < 0) | ||
3139 | return 1; | ||
3140 | /* fall through */ | ||
3141 | default: /* 7 */ | ||
3142 | if (val & 0xffffffff00000000ULL) { | ||
3143 | kvm_inject_gp(vcpu, 0); | ||
3144 | return 1; | ||
3145 | } | ||
3146 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; | ||
3147 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
3148 | vmcs_writel(GUEST_DR7, vcpu->arch.dr7); | ||
3149 | vcpu->arch.switch_db_regs = | ||
3150 | (val & DR7_BP_EN_MASK); | ||
3151 | } | ||
3152 | break; | ||
3153 | } | ||
3154 | } | ||
3155 | skip_emulated_instruction(vcpu); | 3134 | skip_emulated_instruction(vcpu); |
3156 | return 1; | 3135 | return 1; |
3157 | } | 3136 | } |
3158 | 3137 | ||
3138 | static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) | ||
3139 | { | ||
3140 | vmcs_writel(GUEST_DR7, val); | ||
3141 | } | ||
3142 | |||
3159 | static int handle_cpuid(struct kvm_vcpu *vcpu) | 3143 | static int handle_cpuid(struct kvm_vcpu *vcpu) |
3160 | { | 3144 | { |
3161 | kvm_emulate_cpuid(vcpu); | 3145 | kvm_emulate_cpuid(vcpu); |
@@ -3287,6 +3271,8 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) | |||
3287 | { | 3271 | { |
3288 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 3272 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
3289 | unsigned long exit_qualification; | 3273 | unsigned long exit_qualification; |
3274 | bool has_error_code = false; | ||
3275 | u32 error_code = 0; | ||
3290 | u16 tss_selector; | 3276 | u16 tss_selector; |
3291 | int reason, type, idt_v; | 3277 | int reason, type, idt_v; |
3292 | 3278 | ||
@@ -3309,6 +3295,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) | |||
3309 | kvm_clear_interrupt_queue(vcpu); | 3295 | kvm_clear_interrupt_queue(vcpu); |
3310 | break; | 3296 | break; |
3311 | case INTR_TYPE_HARD_EXCEPTION: | 3297 | case INTR_TYPE_HARD_EXCEPTION: |
3298 | if (vmx->idt_vectoring_info & | ||
3299 | VECTORING_INFO_DELIVER_CODE_MASK) { | ||
3300 | has_error_code = true; | ||
3301 | error_code = | ||
3302 | vmcs_read32(IDT_VECTORING_ERROR_CODE); | ||
3303 | } | ||
3304 | /* fall through */ | ||
3312 | case INTR_TYPE_SOFT_EXCEPTION: | 3305 | case INTR_TYPE_SOFT_EXCEPTION: |
3313 | kvm_clear_exception_queue(vcpu); | 3306 | kvm_clear_exception_queue(vcpu); |
3314 | break; | 3307 | break; |
@@ -3323,8 +3316,13 @@ static int handle_task_switch(struct kvm_vcpu *vcpu) | |||
3323 | type != INTR_TYPE_NMI_INTR)) | 3316 | type != INTR_TYPE_NMI_INTR)) |
3324 | skip_emulated_instruction(vcpu); | 3317 | skip_emulated_instruction(vcpu); |
3325 | 3318 | ||
3326 | if (!kvm_task_switch(vcpu, tss_selector, reason)) | 3319 | if (kvm_task_switch(vcpu, tss_selector, reason, |
3320 | has_error_code, error_code) == EMULATE_FAIL) { | ||
3321 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
3322 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||
3323 | vcpu->run->internal.ndata = 0; | ||
3327 | return 0; | 3324 | return 0; |
3325 | } | ||
3328 | 3326 | ||
3329 | /* clear all local breakpoint enable flags */ | 3327 | /* clear all local breakpoint enable flags */ |
3330 | vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~55); | 3328 | vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~55); |
@@ -3569,7 +3567,7 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) | |||
3569 | u32 exit_reason = vmx->exit_reason; | 3567 | u32 exit_reason = vmx->exit_reason; |
3570 | u32 vectoring_info = vmx->idt_vectoring_info; | 3568 | u32 vectoring_info = vmx->idt_vectoring_info; |
3571 | 3569 | ||
3572 | trace_kvm_exit(exit_reason, kvm_rip_read(vcpu)); | 3570 | trace_kvm_exit(exit_reason, vcpu); |
3573 | 3571 | ||
3574 | /* If guest state is invalid, start emulating */ | 3572 | /* If guest state is invalid, start emulating */ |
3575 | if (vmx->emulation_required && emulate_invalid_guest_state) | 3573 | if (vmx->emulation_required && emulate_invalid_guest_state) |
@@ -4149,6 +4147,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4149 | .set_idt = vmx_set_idt, | 4147 | .set_idt = vmx_set_idt, |
4150 | .get_gdt = vmx_get_gdt, | 4148 | .get_gdt = vmx_get_gdt, |
4151 | .set_gdt = vmx_set_gdt, | 4149 | .set_gdt = vmx_set_gdt, |
4150 | .set_dr7 = vmx_set_dr7, | ||
4152 | .cache_reg = vmx_cache_reg, | 4151 | .cache_reg = vmx_cache_reg, |
4153 | .get_rflags = vmx_get_rflags, | 4152 | .get_rflags = vmx_get_rflags, |
4154 | .set_rflags = vmx_set_rflags, | 4153 | .set_rflags = vmx_set_rflags, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c3a33b2bb169..58a96e6a234c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/perf_event.h> | 43 | #include <linux/perf_event.h> |
44 | #include <trace/events/kvm.h> | 44 | #include <trace/events/kvm.h> |
45 | #undef TRACE_INCLUDE_FILE | 45 | |
46 | #define CREATE_TRACE_POINTS | 46 | #define CREATE_TRACE_POINTS |
47 | #include "trace.h" | 47 | #include "trace.h" |
48 | 48 | ||
@@ -224,34 +224,6 @@ static void drop_user_return_notifiers(void *ignore) | |||
224 | kvm_on_user_return(&smsr->urn); | 224 | kvm_on_user_return(&smsr->urn); |
225 | } | 225 | } |
226 | 226 | ||
227 | unsigned long segment_base(u16 selector) | ||
228 | { | ||
229 | struct descriptor_table gdt; | ||
230 | struct desc_struct *d; | ||
231 | unsigned long table_base; | ||
232 | unsigned long v; | ||
233 | |||
234 | if (selector == 0) | ||
235 | return 0; | ||
236 | |||
237 | kvm_get_gdt(&gdt); | ||
238 | table_base = gdt.base; | ||
239 | |||
240 | if (selector & 4) { /* from ldt */ | ||
241 | u16 ldt_selector = kvm_read_ldt(); | ||
242 | |||
243 | table_base = segment_base(ldt_selector); | ||
244 | } | ||
245 | d = (struct desc_struct *)(table_base + (selector & ~7)); | ||
246 | v = get_desc_base(d); | ||
247 | #ifdef CONFIG_X86_64 | ||
248 | if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) | ||
249 | v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; | ||
250 | #endif | ||
251 | return v; | ||
252 | } | ||
253 | EXPORT_SYMBOL_GPL(segment_base); | ||
254 | |||
255 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) | 227 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) |
256 | { | 228 | { |
257 | if (irqchip_in_kernel(vcpu->kvm)) | 229 | if (irqchip_in_kernel(vcpu->kvm)) |
@@ -434,8 +406,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
434 | 406 | ||
435 | #ifdef CONFIG_X86_64 | 407 | #ifdef CONFIG_X86_64 |
436 | if (cr0 & 0xffffffff00000000UL) { | 408 | if (cr0 & 0xffffffff00000000UL) { |
437 | printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", | ||
438 | cr0, kvm_read_cr0(vcpu)); | ||
439 | kvm_inject_gp(vcpu, 0); | 409 | kvm_inject_gp(vcpu, 0); |
440 | return; | 410 | return; |
441 | } | 411 | } |
@@ -444,14 +414,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
444 | cr0 &= ~CR0_RESERVED_BITS; | 414 | cr0 &= ~CR0_RESERVED_BITS; |
445 | 415 | ||
446 | if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { | 416 | if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) { |
447 | printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n"); | ||
448 | kvm_inject_gp(vcpu, 0); | 417 | kvm_inject_gp(vcpu, 0); |
449 | return; | 418 | return; |
450 | } | 419 | } |
451 | 420 | ||
452 | if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { | 421 | if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) { |
453 | printk(KERN_DEBUG "set_cr0: #GP, set PG flag " | ||
454 | "and a clear PE flag\n"); | ||
455 | kvm_inject_gp(vcpu, 0); | 422 | kvm_inject_gp(vcpu, 0); |
456 | return; | 423 | return; |
457 | } | 424 | } |
@@ -462,15 +429,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
462 | int cs_db, cs_l; | 429 | int cs_db, cs_l; |
463 | 430 | ||
464 | if (!is_pae(vcpu)) { | 431 | if (!is_pae(vcpu)) { |
465 | printk(KERN_DEBUG "set_cr0: #GP, start paging " | ||
466 | "in long mode while PAE is disabled\n"); | ||
467 | kvm_inject_gp(vcpu, 0); | 432 | kvm_inject_gp(vcpu, 0); |
468 | return; | 433 | return; |
469 | } | 434 | } |
470 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); | 435 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); |
471 | if (cs_l) { | 436 | if (cs_l) { |
472 | printk(KERN_DEBUG "set_cr0: #GP, start paging " | ||
473 | "in long mode while CS.L == 1\n"); | ||
474 | kvm_inject_gp(vcpu, 0); | 437 | kvm_inject_gp(vcpu, 0); |
475 | return; | 438 | return; |
476 | 439 | ||
@@ -478,8 +441,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
478 | } else | 441 | } else |
479 | #endif | 442 | #endif |
480 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) { | 443 | if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) { |
481 | printk(KERN_DEBUG "set_cr0: #GP, pdptrs " | ||
482 | "reserved bits\n"); | ||
483 | kvm_inject_gp(vcpu, 0); | 444 | kvm_inject_gp(vcpu, 0); |
484 | return; | 445 | return; |
485 | } | 446 | } |
@@ -487,7 +448,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
487 | } | 448 | } |
488 | 449 | ||
489 | kvm_x86_ops->set_cr0(vcpu, cr0); | 450 | kvm_x86_ops->set_cr0(vcpu, cr0); |
490 | vcpu->arch.cr0 = cr0; | ||
491 | 451 | ||
492 | kvm_mmu_reset_context(vcpu); | 452 | kvm_mmu_reset_context(vcpu); |
493 | return; | 453 | return; |
@@ -506,28 +466,23 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
506 | unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE; | 466 | unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE; |
507 | 467 | ||
508 | if (cr4 & CR4_RESERVED_BITS) { | 468 | if (cr4 & CR4_RESERVED_BITS) { |
509 | printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n"); | ||
510 | kvm_inject_gp(vcpu, 0); | 469 | kvm_inject_gp(vcpu, 0); |
511 | return; | 470 | return; |
512 | } | 471 | } |
513 | 472 | ||
514 | if (is_long_mode(vcpu)) { | 473 | if (is_long_mode(vcpu)) { |
515 | if (!(cr4 & X86_CR4_PAE)) { | 474 | if (!(cr4 & X86_CR4_PAE)) { |
516 | printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while " | ||
517 | "in long mode\n"); | ||
518 | kvm_inject_gp(vcpu, 0); | 475 | kvm_inject_gp(vcpu, 0); |
519 | return; | 476 | return; |
520 | } | 477 | } |
521 | } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) | 478 | } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE) |
522 | && ((cr4 ^ old_cr4) & pdptr_bits) | 479 | && ((cr4 ^ old_cr4) & pdptr_bits) |
523 | && !load_pdptrs(vcpu, vcpu->arch.cr3)) { | 480 | && !load_pdptrs(vcpu, vcpu->arch.cr3)) { |
524 | printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n"); | ||
525 | kvm_inject_gp(vcpu, 0); | 481 | kvm_inject_gp(vcpu, 0); |
526 | return; | 482 | return; |
527 | } | 483 | } |
528 | 484 | ||
529 | if (cr4 & X86_CR4_VMXE) { | 485 | if (cr4 & X86_CR4_VMXE) { |
530 | printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n"); | ||
531 | kvm_inject_gp(vcpu, 0); | 486 | kvm_inject_gp(vcpu, 0); |
532 | return; | 487 | return; |
533 | } | 488 | } |
@@ -548,21 +503,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
548 | 503 | ||
549 | if (is_long_mode(vcpu)) { | 504 | if (is_long_mode(vcpu)) { |
550 | if (cr3 & CR3_L_MODE_RESERVED_BITS) { | 505 | if (cr3 & CR3_L_MODE_RESERVED_BITS) { |
551 | printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); | ||
552 | kvm_inject_gp(vcpu, 0); | 506 | kvm_inject_gp(vcpu, 0); |
553 | return; | 507 | return; |
554 | } | 508 | } |
555 | } else { | 509 | } else { |
556 | if (is_pae(vcpu)) { | 510 | if (is_pae(vcpu)) { |
557 | if (cr3 & CR3_PAE_RESERVED_BITS) { | 511 | if (cr3 & CR3_PAE_RESERVED_BITS) { |
558 | printk(KERN_DEBUG | ||
559 | "set_cr3: #GP, reserved bits\n"); | ||
560 | kvm_inject_gp(vcpu, 0); | 512 | kvm_inject_gp(vcpu, 0); |
561 | return; | 513 | return; |
562 | } | 514 | } |
563 | if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { | 515 | if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) { |
564 | printk(KERN_DEBUG "set_cr3: #GP, pdptrs " | ||
565 | "reserved bits\n"); | ||
566 | kvm_inject_gp(vcpu, 0); | 516 | kvm_inject_gp(vcpu, 0); |
567 | return; | 517 | return; |
568 | } | 518 | } |
@@ -594,7 +544,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3); | |||
594 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | 544 | void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) |
595 | { | 545 | { |
596 | if (cr8 & CR8_RESERVED_BITS) { | 546 | if (cr8 & CR8_RESERVED_BITS) { |
597 | printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8); | ||
598 | kvm_inject_gp(vcpu, 0); | 547 | kvm_inject_gp(vcpu, 0); |
599 | return; | 548 | return; |
600 | } | 549 | } |
@@ -614,6 +563,80 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) | |||
614 | } | 563 | } |
615 | EXPORT_SYMBOL_GPL(kvm_get_cr8); | 564 | EXPORT_SYMBOL_GPL(kvm_get_cr8); |
616 | 565 | ||
566 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | ||
567 | { | ||
568 | switch (dr) { | ||
569 | case 0 ... 3: | ||
570 | vcpu->arch.db[dr] = val; | ||
571 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | ||
572 | vcpu->arch.eff_db[dr] = val; | ||
573 | break; | ||
574 | case 4: | ||
575 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
576 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
577 | return 1; | ||
578 | } | ||
579 | /* fall through */ | ||
580 | case 6: | ||
581 | if (val & 0xffffffff00000000ULL) { | ||
582 | kvm_inject_gp(vcpu, 0); | ||
583 | return 1; | ||
584 | } | ||
585 | vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; | ||
586 | break; | ||
587 | case 5: | ||
588 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
589 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
590 | return 1; | ||
591 | } | ||
592 | /* fall through */ | ||
593 | default: /* 7 */ | ||
594 | if (val & 0xffffffff00000000ULL) { | ||
595 | kvm_inject_gp(vcpu, 0); | ||
596 | return 1; | ||
597 | } | ||
598 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; | ||
599 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
600 | kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7); | ||
601 | vcpu->arch.switch_db_regs = (val & DR7_BP_EN_MASK); | ||
602 | } | ||
603 | break; | ||
604 | } | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | EXPORT_SYMBOL_GPL(kvm_set_dr); | ||
609 | |||
610 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) | ||
611 | { | ||
612 | switch (dr) { | ||
613 | case 0 ... 3: | ||
614 | *val = vcpu->arch.db[dr]; | ||
615 | break; | ||
616 | case 4: | ||
617 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
618 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
619 | return 1; | ||
620 | } | ||
621 | /* fall through */ | ||
622 | case 6: | ||
623 | *val = vcpu->arch.dr6; | ||
624 | break; | ||
625 | case 5: | ||
626 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
627 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
628 | return 1; | ||
629 | } | ||
630 | /* fall through */ | ||
631 | default: /* 7 */ | ||
632 | *val = vcpu->arch.dr7; | ||
633 | break; | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | EXPORT_SYMBOL_GPL(kvm_get_dr); | ||
639 | |||
617 | static inline u32 bit(int bitno) | 640 | static inline u32 bit(int bitno) |
618 | { | 641 | { |
619 | return 1 << (bitno & 31); | 642 | return 1 << (bitno & 31); |
@@ -650,15 +673,12 @@ static u32 emulated_msrs[] = { | |||
650 | static void set_efer(struct kvm_vcpu *vcpu, u64 efer) | 673 | static void set_efer(struct kvm_vcpu *vcpu, u64 efer) |
651 | { | 674 | { |
652 | if (efer & efer_reserved_bits) { | 675 | if (efer & efer_reserved_bits) { |
653 | printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", | ||
654 | efer); | ||
655 | kvm_inject_gp(vcpu, 0); | 676 | kvm_inject_gp(vcpu, 0); |
656 | return; | 677 | return; |
657 | } | 678 | } |
658 | 679 | ||
659 | if (is_paging(vcpu) | 680 | if (is_paging(vcpu) |
660 | && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) { | 681 | && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) { |
661 | printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n"); | ||
662 | kvm_inject_gp(vcpu, 0); | 682 | kvm_inject_gp(vcpu, 0); |
663 | return; | 683 | return; |
664 | } | 684 | } |
@@ -668,7 +688,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
668 | 688 | ||
669 | feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); | 689 | feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); |
670 | if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) { | 690 | if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) { |
671 | printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n"); | ||
672 | kvm_inject_gp(vcpu, 0); | 691 | kvm_inject_gp(vcpu, 0); |
673 | return; | 692 | return; |
674 | } | 693 | } |
@@ -679,7 +698,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
679 | 698 | ||
680 | feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); | 699 | feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); |
681 | if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) { | 700 | if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) { |
682 | printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n"); | ||
683 | kvm_inject_gp(vcpu, 0); | 701 | kvm_inject_gp(vcpu, 0); |
684 | return; | 702 | return; |
685 | } | 703 | } |
@@ -968,9 +986,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
968 | if (msr >= MSR_IA32_MC0_CTL && | 986 | if (msr >= MSR_IA32_MC0_CTL && |
969 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { | 987 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { |
970 | u32 offset = msr - MSR_IA32_MC0_CTL; | 988 | u32 offset = msr - MSR_IA32_MC0_CTL; |
971 | /* only 0 or all 1s can be written to IA32_MCi_CTL */ | 989 | /* only 0 or all 1s can be written to IA32_MCi_CTL |
990 | * some Linux kernels though clear bit 10 in bank 4 to | ||
991 | * workaround a BIOS/GART TBL issue on AMD K8s, ignore | ||
992 | * this to avoid an uncatched #GP in the guest | ||
993 | */ | ||
972 | if ((offset & 0x3) == 0 && | 994 | if ((offset & 0x3) == 0 && |
973 | data != 0 && data != ~(u64)0) | 995 | data != 0 && (data | (1 << 10)) != ~(u64)0) |
974 | return -1; | 996 | return -1; |
975 | vcpu->arch.mce_banks[offset] = data; | 997 | vcpu->arch.mce_banks[offset] = data; |
976 | break; | 998 | break; |
@@ -1114,6 +1136,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1114 | break; | 1136 | break; |
1115 | case MSR_K7_HWCR: | 1137 | case MSR_K7_HWCR: |
1116 | data &= ~(u64)0x40; /* ignore flush filter disable */ | 1138 | data &= ~(u64)0x40; /* ignore flush filter disable */ |
1139 | data &= ~(u64)0x100; /* ignore ignne emulation enable */ | ||
1117 | if (data != 0) { | 1140 | if (data != 0) { |
1118 | pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", | 1141 | pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", |
1119 | data); | 1142 | data); |
@@ -1572,6 +1595,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
1572 | case KVM_CAP_HYPERV_VAPIC: | 1595 | case KVM_CAP_HYPERV_VAPIC: |
1573 | case KVM_CAP_HYPERV_SPIN: | 1596 | case KVM_CAP_HYPERV_SPIN: |
1574 | case KVM_CAP_PCI_SEGMENT: | 1597 | case KVM_CAP_PCI_SEGMENT: |
1598 | case KVM_CAP_DEBUGREGS: | ||
1575 | case KVM_CAP_X86_ROBUST_SINGLESTEP: | 1599 | case KVM_CAP_X86_ROBUST_SINGLESTEP: |
1576 | r = 1; | 1600 | r = 1; |
1577 | break; | 1601 | break; |
@@ -2124,14 +2148,20 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2124 | { | 2148 | { |
2125 | vcpu_load(vcpu); | 2149 | vcpu_load(vcpu); |
2126 | 2150 | ||
2127 | events->exception.injected = vcpu->arch.exception.pending; | 2151 | events->exception.injected = |
2152 | vcpu->arch.exception.pending && | ||
2153 | !kvm_exception_is_soft(vcpu->arch.exception.nr); | ||
2128 | events->exception.nr = vcpu->arch.exception.nr; | 2154 | events->exception.nr = vcpu->arch.exception.nr; |
2129 | events->exception.has_error_code = vcpu->arch.exception.has_error_code; | 2155 | events->exception.has_error_code = vcpu->arch.exception.has_error_code; |
2130 | events->exception.error_code = vcpu->arch.exception.error_code; | 2156 | events->exception.error_code = vcpu->arch.exception.error_code; |
2131 | 2157 | ||
2132 | events->interrupt.injected = vcpu->arch.interrupt.pending; | 2158 | events->interrupt.injected = |
2159 | vcpu->arch.interrupt.pending && !vcpu->arch.interrupt.soft; | ||
2133 | events->interrupt.nr = vcpu->arch.interrupt.nr; | 2160 | events->interrupt.nr = vcpu->arch.interrupt.nr; |
2134 | events->interrupt.soft = vcpu->arch.interrupt.soft; | 2161 | events->interrupt.soft = 0; |
2162 | events->interrupt.shadow = | ||
2163 | kvm_x86_ops->get_interrupt_shadow(vcpu, | ||
2164 | KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI); | ||
2135 | 2165 | ||
2136 | events->nmi.injected = vcpu->arch.nmi_injected; | 2166 | events->nmi.injected = vcpu->arch.nmi_injected; |
2137 | events->nmi.pending = vcpu->arch.nmi_pending; | 2167 | events->nmi.pending = vcpu->arch.nmi_pending; |
@@ -2140,7 +2170,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, | |||
2140 | events->sipi_vector = vcpu->arch.sipi_vector; | 2170 | events->sipi_vector = vcpu->arch.sipi_vector; |
2141 | 2171 | ||
2142 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | 2172 | events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING |
2143 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR); | 2173 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR |
2174 | | KVM_VCPUEVENT_VALID_SHADOW); | ||
2144 | 2175 | ||
2145 | vcpu_put(vcpu); | 2176 | vcpu_put(vcpu); |
2146 | } | 2177 | } |
@@ -2149,7 +2180,8 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
2149 | struct kvm_vcpu_events *events) | 2180 | struct kvm_vcpu_events *events) |
2150 | { | 2181 | { |
2151 | if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING | 2182 | if (events->flags & ~(KVM_VCPUEVENT_VALID_NMI_PENDING |
2152 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR)) | 2183 | | KVM_VCPUEVENT_VALID_SIPI_VECTOR |
2184 | | KVM_VCPUEVENT_VALID_SHADOW)) | ||
2153 | return -EINVAL; | 2185 | return -EINVAL; |
2154 | 2186 | ||
2155 | vcpu_load(vcpu); | 2187 | vcpu_load(vcpu); |
@@ -2164,6 +2196,9 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
2164 | vcpu->arch.interrupt.soft = events->interrupt.soft; | 2196 | vcpu->arch.interrupt.soft = events->interrupt.soft; |
2165 | if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm)) | 2197 | if (vcpu->arch.interrupt.pending && irqchip_in_kernel(vcpu->kvm)) |
2166 | kvm_pic_clear_isr_ack(vcpu->kvm); | 2198 | kvm_pic_clear_isr_ack(vcpu->kvm); |
2199 | if (events->flags & KVM_VCPUEVENT_VALID_SHADOW) | ||
2200 | kvm_x86_ops->set_interrupt_shadow(vcpu, | ||
2201 | events->interrupt.shadow); | ||
2167 | 2202 | ||
2168 | vcpu->arch.nmi_injected = events->nmi.injected; | 2203 | vcpu->arch.nmi_injected = events->nmi.injected; |
2169 | if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) | 2204 | if (events->flags & KVM_VCPUEVENT_VALID_NMI_PENDING) |
@@ -2178,6 +2213,36 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, | |||
2178 | return 0; | 2213 | return 0; |
2179 | } | 2214 | } |
2180 | 2215 | ||
2216 | static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, | ||
2217 | struct kvm_debugregs *dbgregs) | ||
2218 | { | ||
2219 | vcpu_load(vcpu); | ||
2220 | |||
2221 | memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db)); | ||
2222 | dbgregs->dr6 = vcpu->arch.dr6; | ||
2223 | dbgregs->dr7 = vcpu->arch.dr7; | ||
2224 | dbgregs->flags = 0; | ||
2225 | |||
2226 | vcpu_put(vcpu); | ||
2227 | } | ||
2228 | |||
2229 | static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, | ||
2230 | struct kvm_debugregs *dbgregs) | ||
2231 | { | ||
2232 | if (dbgregs->flags) | ||
2233 | return -EINVAL; | ||
2234 | |||
2235 | vcpu_load(vcpu); | ||
2236 | |||
2237 | memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db)); | ||
2238 | vcpu->arch.dr6 = dbgregs->dr6; | ||
2239 | vcpu->arch.dr7 = dbgregs->dr7; | ||
2240 | |||
2241 | vcpu_put(vcpu); | ||
2242 | |||
2243 | return 0; | ||
2244 | } | ||
2245 | |||
2181 | long kvm_arch_vcpu_ioctl(struct file *filp, | 2246 | long kvm_arch_vcpu_ioctl(struct file *filp, |
2182 | unsigned int ioctl, unsigned long arg) | 2247 | unsigned int ioctl, unsigned long arg) |
2183 | { | 2248 | { |
@@ -2356,6 +2421,29 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
2356 | r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events); | 2421 | r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events); |
2357 | break; | 2422 | break; |
2358 | } | 2423 | } |
2424 | case KVM_GET_DEBUGREGS: { | ||
2425 | struct kvm_debugregs dbgregs; | ||
2426 | |||
2427 | kvm_vcpu_ioctl_x86_get_debugregs(vcpu, &dbgregs); | ||
2428 | |||
2429 | r = -EFAULT; | ||
2430 | if (copy_to_user(argp, &dbgregs, | ||
2431 | sizeof(struct kvm_debugregs))) | ||
2432 | break; | ||
2433 | r = 0; | ||
2434 | break; | ||
2435 | } | ||
2436 | case KVM_SET_DEBUGREGS: { | ||
2437 | struct kvm_debugregs dbgregs; | ||
2438 | |||
2439 | r = -EFAULT; | ||
2440 | if (copy_from_user(&dbgregs, argp, | ||
2441 | sizeof(struct kvm_debugregs))) | ||
2442 | break; | ||
2443 | |||
2444 | r = kvm_vcpu_ioctl_x86_set_debugregs(vcpu, &dbgregs); | ||
2445 | break; | ||
2446 | } | ||
2359 | default: | 2447 | default: |
2360 | r = -EINVAL; | 2448 | r = -EINVAL; |
2361 | } | 2449 | } |
@@ -2636,8 +2724,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm, | |||
2636 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | 2724 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, |
2637 | struct kvm_dirty_log *log) | 2725 | struct kvm_dirty_log *log) |
2638 | { | 2726 | { |
2639 | int r, n, i; | 2727 | int r, i; |
2640 | struct kvm_memory_slot *memslot; | 2728 | struct kvm_memory_slot *memslot; |
2729 | unsigned long n; | ||
2641 | unsigned long is_dirty = 0; | 2730 | unsigned long is_dirty = 0; |
2642 | unsigned long *dirty_bitmap = NULL; | 2731 | unsigned long *dirty_bitmap = NULL; |
2643 | 2732 | ||
@@ -2652,7 +2741,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
2652 | if (!memslot->dirty_bitmap) | 2741 | if (!memslot->dirty_bitmap) |
2653 | goto out; | 2742 | goto out; |
2654 | 2743 | ||
2655 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 2744 | n = kvm_dirty_bitmap_bytes(memslot); |
2656 | 2745 | ||
2657 | r = -ENOMEM; | 2746 | r = -ENOMEM; |
2658 | dirty_bitmap = vmalloc(n); | 2747 | dirty_bitmap = vmalloc(n); |
@@ -2822,11 +2911,13 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
2822 | r = -EFAULT; | 2911 | r = -EFAULT; |
2823 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | 2912 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) |
2824 | goto out; | 2913 | goto out; |
2914 | r = -ENXIO; | ||
2825 | if (irqchip_in_kernel(kvm)) { | 2915 | if (irqchip_in_kernel(kvm)) { |
2826 | __s32 status; | 2916 | __s32 status; |
2827 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 2917 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
2828 | irq_event.irq, irq_event.level); | 2918 | irq_event.irq, irq_event.level); |
2829 | if (ioctl == KVM_IRQ_LINE_STATUS) { | 2919 | if (ioctl == KVM_IRQ_LINE_STATUS) { |
2920 | r = -EFAULT; | ||
2830 | irq_event.status = status; | 2921 | irq_event.status = status; |
2831 | if (copy_to_user(argp, &irq_event, | 2922 | if (copy_to_user(argp, &irq_event, |
2832 | sizeof irq_event)) | 2923 | sizeof irq_event)) |
@@ -3042,6 +3133,18 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) | |||
3042 | return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v); | 3133 | return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v); |
3043 | } | 3134 | } |
3044 | 3135 | ||
3136 | static void kvm_set_segment(struct kvm_vcpu *vcpu, | ||
3137 | struct kvm_segment *var, int seg) | ||
3138 | { | ||
3139 | kvm_x86_ops->set_segment(vcpu, var, seg); | ||
3140 | } | ||
3141 | |||
3142 | void kvm_get_segment(struct kvm_vcpu *vcpu, | ||
3143 | struct kvm_segment *var, int seg) | ||
3144 | { | ||
3145 | kvm_x86_ops->get_segment(vcpu, var, seg); | ||
3146 | } | ||
3147 | |||
3045 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) | 3148 | gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, u32 *error) |
3046 | { | 3149 | { |
3047 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; | 3150 | u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; |
@@ -3122,14 +3225,17 @@ static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes, | |||
3122 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); | 3225 | return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error); |
3123 | } | 3226 | } |
3124 | 3227 | ||
3125 | static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes, | 3228 | static int kvm_write_guest_virt_system(gva_t addr, void *val, |
3126 | struct kvm_vcpu *vcpu, u32 *error) | 3229 | unsigned int bytes, |
3230 | struct kvm_vcpu *vcpu, | ||
3231 | u32 *error) | ||
3127 | { | 3232 | { |
3128 | void *data = val; | 3233 | void *data = val; |
3129 | int r = X86EMUL_CONTINUE; | 3234 | int r = X86EMUL_CONTINUE; |
3130 | 3235 | ||
3131 | while (bytes) { | 3236 | while (bytes) { |
3132 | gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error); | 3237 | gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr, |
3238 | PFERR_WRITE_MASK, error); | ||
3133 | unsigned offset = addr & (PAGE_SIZE-1); | 3239 | unsigned offset = addr & (PAGE_SIZE-1); |
3134 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); | 3240 | unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); |
3135 | int ret; | 3241 | int ret; |
@@ -3152,7 +3258,6 @@ out: | |||
3152 | return r; | 3258 | return r; |
3153 | } | 3259 | } |
3154 | 3260 | ||
3155 | |||
3156 | static int emulator_read_emulated(unsigned long addr, | 3261 | static int emulator_read_emulated(unsigned long addr, |
3157 | void *val, | 3262 | void *val, |
3158 | unsigned int bytes, | 3263 | unsigned int bytes, |
@@ -3255,9 +3360,9 @@ mmio: | |||
3255 | } | 3360 | } |
3256 | 3361 | ||
3257 | int emulator_write_emulated(unsigned long addr, | 3362 | int emulator_write_emulated(unsigned long addr, |
3258 | const void *val, | 3363 | const void *val, |
3259 | unsigned int bytes, | 3364 | unsigned int bytes, |
3260 | struct kvm_vcpu *vcpu) | 3365 | struct kvm_vcpu *vcpu) |
3261 | { | 3366 | { |
3262 | /* Crossing a page boundary? */ | 3367 | /* Crossing a page boundary? */ |
3263 | if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { | 3368 | if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { |
@@ -3275,45 +3380,150 @@ int emulator_write_emulated(unsigned long addr, | |||
3275 | } | 3380 | } |
3276 | EXPORT_SYMBOL_GPL(emulator_write_emulated); | 3381 | EXPORT_SYMBOL_GPL(emulator_write_emulated); |
3277 | 3382 | ||
3383 | #define CMPXCHG_TYPE(t, ptr, old, new) \ | ||
3384 | (cmpxchg((t *)(ptr), *(t *)(old), *(t *)(new)) == *(t *)(old)) | ||
3385 | |||
3386 | #ifdef CONFIG_X86_64 | ||
3387 | # define CMPXCHG64(ptr, old, new) CMPXCHG_TYPE(u64, ptr, old, new) | ||
3388 | #else | ||
3389 | # define CMPXCHG64(ptr, old, new) \ | ||
3390 | (cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u64 *)(new)) == *(u64 *)(old)) | ||
3391 | #endif | ||
3392 | |||
3278 | static int emulator_cmpxchg_emulated(unsigned long addr, | 3393 | static int emulator_cmpxchg_emulated(unsigned long addr, |
3279 | const void *old, | 3394 | const void *old, |
3280 | const void *new, | 3395 | const void *new, |
3281 | unsigned int bytes, | 3396 | unsigned int bytes, |
3282 | struct kvm_vcpu *vcpu) | 3397 | struct kvm_vcpu *vcpu) |
3283 | { | 3398 | { |
3284 | printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); | 3399 | gpa_t gpa; |
3285 | #ifndef CONFIG_X86_64 | 3400 | struct page *page; |
3286 | /* guests cmpxchg8b have to be emulated atomically */ | 3401 | char *kaddr; |
3287 | if (bytes == 8) { | 3402 | bool exchanged; |
3288 | gpa_t gpa; | ||
3289 | struct page *page; | ||
3290 | char *kaddr; | ||
3291 | u64 val; | ||
3292 | 3403 | ||
3293 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL); | 3404 | /* guests cmpxchg8b have to be emulated atomically */ |
3405 | if (bytes > 8 || (bytes & (bytes - 1))) | ||
3406 | goto emul_write; | ||
3294 | 3407 | ||
3295 | if (gpa == UNMAPPED_GVA || | 3408 | gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL); |
3296 | (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) | ||
3297 | goto emul_write; | ||
3298 | 3409 | ||
3299 | if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) | 3410 | if (gpa == UNMAPPED_GVA || |
3300 | goto emul_write; | 3411 | (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) |
3412 | goto emul_write; | ||
3301 | 3413 | ||
3302 | val = *(u64 *)new; | 3414 | if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK)) |
3415 | goto emul_write; | ||
3303 | 3416 | ||
3304 | page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); | 3417 | page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); |
3305 | 3418 | ||
3306 | kaddr = kmap_atomic(page, KM_USER0); | 3419 | kaddr = kmap_atomic(page, KM_USER0); |
3307 | set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val); | 3420 | kaddr += offset_in_page(gpa); |
3308 | kunmap_atomic(kaddr, KM_USER0); | 3421 | switch (bytes) { |
3309 | kvm_release_page_dirty(page); | 3422 | case 1: |
3423 | exchanged = CMPXCHG_TYPE(u8, kaddr, old, new); | ||
3424 | break; | ||
3425 | case 2: | ||
3426 | exchanged = CMPXCHG_TYPE(u16, kaddr, old, new); | ||
3427 | break; | ||
3428 | case 4: | ||
3429 | exchanged = CMPXCHG_TYPE(u32, kaddr, old, new); | ||
3430 | break; | ||
3431 | case 8: | ||
3432 | exchanged = CMPXCHG64(kaddr, old, new); | ||
3433 | break; | ||
3434 | default: | ||
3435 | BUG(); | ||
3310 | } | 3436 | } |
3437 | kunmap_atomic(kaddr, KM_USER0); | ||
3438 | kvm_release_page_dirty(page); | ||
3439 | |||
3440 | if (!exchanged) | ||
3441 | return X86EMUL_CMPXCHG_FAILED; | ||
3442 | |||
3443 | kvm_mmu_pte_write(vcpu, gpa, new, bytes, 1); | ||
3444 | |||
3445 | return X86EMUL_CONTINUE; | ||
3446 | |||
3311 | emul_write: | 3447 | emul_write: |
3312 | #endif | 3448 | printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); |
3313 | 3449 | ||
3314 | return emulator_write_emulated(addr, new, bytes, vcpu); | 3450 | return emulator_write_emulated(addr, new, bytes, vcpu); |
3315 | } | 3451 | } |
3316 | 3452 | ||
3453 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) | ||
3454 | { | ||
3455 | /* TODO: String I/O for in kernel device */ | ||
3456 | int r; | ||
3457 | |||
3458 | if (vcpu->arch.pio.in) | ||
3459 | r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port, | ||
3460 | vcpu->arch.pio.size, pd); | ||
3461 | else | ||
3462 | r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, | ||
3463 | vcpu->arch.pio.port, vcpu->arch.pio.size, | ||
3464 | pd); | ||
3465 | return r; | ||
3466 | } | ||
3467 | |||
3468 | |||
3469 | static int emulator_pio_in_emulated(int size, unsigned short port, void *val, | ||
3470 | unsigned int count, struct kvm_vcpu *vcpu) | ||
3471 | { | ||
3472 | if (vcpu->arch.pio.count) | ||
3473 | goto data_avail; | ||
3474 | |||
3475 | trace_kvm_pio(1, port, size, 1); | ||
3476 | |||
3477 | vcpu->arch.pio.port = port; | ||
3478 | vcpu->arch.pio.in = 1; | ||
3479 | vcpu->arch.pio.count = count; | ||
3480 | vcpu->arch.pio.size = size; | ||
3481 | |||
3482 | if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { | ||
3483 | data_avail: | ||
3484 | memcpy(val, vcpu->arch.pio_data, size * count); | ||
3485 | vcpu->arch.pio.count = 0; | ||
3486 | return 1; | ||
3487 | } | ||
3488 | |||
3489 | vcpu->run->exit_reason = KVM_EXIT_IO; | ||
3490 | vcpu->run->io.direction = KVM_EXIT_IO_IN; | ||
3491 | vcpu->run->io.size = size; | ||
3492 | vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; | ||
3493 | vcpu->run->io.count = count; | ||
3494 | vcpu->run->io.port = port; | ||
3495 | |||
3496 | return 0; | ||
3497 | } | ||
3498 | |||
3499 | static int emulator_pio_out_emulated(int size, unsigned short port, | ||
3500 | const void *val, unsigned int count, | ||
3501 | struct kvm_vcpu *vcpu) | ||
3502 | { | ||
3503 | trace_kvm_pio(0, port, size, 1); | ||
3504 | |||
3505 | vcpu->arch.pio.port = port; | ||
3506 | vcpu->arch.pio.in = 0; | ||
3507 | vcpu->arch.pio.count = count; | ||
3508 | vcpu->arch.pio.size = size; | ||
3509 | |||
3510 | memcpy(vcpu->arch.pio_data, val, size * count); | ||
3511 | |||
3512 | if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { | ||
3513 | vcpu->arch.pio.count = 0; | ||
3514 | return 1; | ||
3515 | } | ||
3516 | |||
3517 | vcpu->run->exit_reason = KVM_EXIT_IO; | ||
3518 | vcpu->run->io.direction = KVM_EXIT_IO_OUT; | ||
3519 | vcpu->run->io.size = size; | ||
3520 | vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; | ||
3521 | vcpu->run->io.count = count; | ||
3522 | vcpu->run->io.port = port; | ||
3523 | |||
3524 | return 0; | ||
3525 | } | ||
3526 | |||
3317 | static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) | 3527 | static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) |
3318 | { | 3528 | { |
3319 | return kvm_x86_ops->get_segment_base(vcpu, seg); | 3529 | return kvm_x86_ops->get_segment_base(vcpu, seg); |
@@ -3334,14 +3544,14 @@ int emulate_clts(struct kvm_vcpu *vcpu) | |||
3334 | 3544 | ||
3335 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) | 3545 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) |
3336 | { | 3546 | { |
3337 | return kvm_x86_ops->get_dr(ctxt->vcpu, dr, dest); | 3547 | return kvm_get_dr(ctxt->vcpu, dr, dest); |
3338 | } | 3548 | } |
3339 | 3549 | ||
3340 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) | 3550 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) |
3341 | { | 3551 | { |
3342 | unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; | 3552 | unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; |
3343 | 3553 | ||
3344 | return kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask); | 3554 | return kvm_set_dr(ctxt->vcpu, dr, value & mask); |
3345 | } | 3555 | } |
3346 | 3556 | ||
3347 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) | 3557 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) |
@@ -3362,12 +3572,167 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) | |||
3362 | } | 3572 | } |
3363 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); | 3573 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); |
3364 | 3574 | ||
3575 | static u64 mk_cr_64(u64 curr_cr, u32 new_val) | ||
3576 | { | ||
3577 | return (curr_cr & ~((1ULL << 32) - 1)) | new_val; | ||
3578 | } | ||
3579 | |||
3580 | static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu) | ||
3581 | { | ||
3582 | unsigned long value; | ||
3583 | |||
3584 | switch (cr) { | ||
3585 | case 0: | ||
3586 | value = kvm_read_cr0(vcpu); | ||
3587 | break; | ||
3588 | case 2: | ||
3589 | value = vcpu->arch.cr2; | ||
3590 | break; | ||
3591 | case 3: | ||
3592 | value = vcpu->arch.cr3; | ||
3593 | break; | ||
3594 | case 4: | ||
3595 | value = kvm_read_cr4(vcpu); | ||
3596 | break; | ||
3597 | case 8: | ||
3598 | value = kvm_get_cr8(vcpu); | ||
3599 | break; | ||
3600 | default: | ||
3601 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | ||
3602 | return 0; | ||
3603 | } | ||
3604 | |||
3605 | return value; | ||
3606 | } | ||
3607 | |||
3608 | static void emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) | ||
3609 | { | ||
3610 | switch (cr) { | ||
3611 | case 0: | ||
3612 | kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); | ||
3613 | break; | ||
3614 | case 2: | ||
3615 | vcpu->arch.cr2 = val; | ||
3616 | break; | ||
3617 | case 3: | ||
3618 | kvm_set_cr3(vcpu, val); | ||
3619 | break; | ||
3620 | case 4: | ||
3621 | kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); | ||
3622 | break; | ||
3623 | case 8: | ||
3624 | kvm_set_cr8(vcpu, val & 0xfUL); | ||
3625 | break; | ||
3626 | default: | ||
3627 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | ||
3628 | } | ||
3629 | } | ||
3630 | |||
3631 | static int emulator_get_cpl(struct kvm_vcpu *vcpu) | ||
3632 | { | ||
3633 | return kvm_x86_ops->get_cpl(vcpu); | ||
3634 | } | ||
3635 | |||
3636 | static void emulator_get_gdt(struct desc_ptr *dt, struct kvm_vcpu *vcpu) | ||
3637 | { | ||
3638 | kvm_x86_ops->get_gdt(vcpu, dt); | ||
3639 | } | ||
3640 | |||
3641 | static bool emulator_get_cached_descriptor(struct desc_struct *desc, int seg, | ||
3642 | struct kvm_vcpu *vcpu) | ||
3643 | { | ||
3644 | struct kvm_segment var; | ||
3645 | |||
3646 | kvm_get_segment(vcpu, &var, seg); | ||
3647 | |||
3648 | if (var.unusable) | ||
3649 | return false; | ||
3650 | |||
3651 | if (var.g) | ||
3652 | var.limit >>= 12; | ||
3653 | set_desc_limit(desc, var.limit); | ||
3654 | set_desc_base(desc, (unsigned long)var.base); | ||
3655 | desc->type = var.type; | ||
3656 | desc->s = var.s; | ||
3657 | desc->dpl = var.dpl; | ||
3658 | desc->p = var.present; | ||
3659 | desc->avl = var.avl; | ||
3660 | desc->l = var.l; | ||
3661 | desc->d = var.db; | ||
3662 | desc->g = var.g; | ||
3663 | |||
3664 | return true; | ||
3665 | } | ||
3666 | |||
3667 | static void emulator_set_cached_descriptor(struct desc_struct *desc, int seg, | ||
3668 | struct kvm_vcpu *vcpu) | ||
3669 | { | ||
3670 | struct kvm_segment var; | ||
3671 | |||
3672 | /* needed to preserve selector */ | ||
3673 | kvm_get_segment(vcpu, &var, seg); | ||
3674 | |||
3675 | var.base = get_desc_base(desc); | ||
3676 | var.limit = get_desc_limit(desc); | ||
3677 | if (desc->g) | ||
3678 | var.limit = (var.limit << 12) | 0xfff; | ||
3679 | var.type = desc->type; | ||
3680 | var.present = desc->p; | ||
3681 | var.dpl = desc->dpl; | ||
3682 | var.db = desc->d; | ||
3683 | var.s = desc->s; | ||
3684 | var.l = desc->l; | ||
3685 | var.g = desc->g; | ||
3686 | var.avl = desc->avl; | ||
3687 | var.present = desc->p; | ||
3688 | var.unusable = !var.present; | ||
3689 | var.padding = 0; | ||
3690 | |||
3691 | kvm_set_segment(vcpu, &var, seg); | ||
3692 | return; | ||
3693 | } | ||
3694 | |||
3695 | static u16 emulator_get_segment_selector(int seg, struct kvm_vcpu *vcpu) | ||
3696 | { | ||
3697 | struct kvm_segment kvm_seg; | ||
3698 | |||
3699 | kvm_get_segment(vcpu, &kvm_seg, seg); | ||
3700 | return kvm_seg.selector; | ||
3701 | } | ||
3702 | |||
3703 | static void emulator_set_segment_selector(u16 sel, int seg, | ||
3704 | struct kvm_vcpu *vcpu) | ||
3705 | { | ||
3706 | struct kvm_segment kvm_seg; | ||
3707 | |||
3708 | kvm_get_segment(vcpu, &kvm_seg, seg); | ||
3709 | kvm_seg.selector = sel; | ||
3710 | kvm_set_segment(vcpu, &kvm_seg, seg); | ||
3711 | } | ||
3712 | |||
3713 | static void emulator_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | ||
3714 | { | ||
3715 | kvm_x86_ops->set_rflags(vcpu, rflags); | ||
3716 | } | ||
3717 | |||
3365 | static struct x86_emulate_ops emulate_ops = { | 3718 | static struct x86_emulate_ops emulate_ops = { |
3366 | .read_std = kvm_read_guest_virt_system, | 3719 | .read_std = kvm_read_guest_virt_system, |
3720 | .write_std = kvm_write_guest_virt_system, | ||
3367 | .fetch = kvm_fetch_guest_virt, | 3721 | .fetch = kvm_fetch_guest_virt, |
3368 | .read_emulated = emulator_read_emulated, | 3722 | .read_emulated = emulator_read_emulated, |
3369 | .write_emulated = emulator_write_emulated, | 3723 | .write_emulated = emulator_write_emulated, |
3370 | .cmpxchg_emulated = emulator_cmpxchg_emulated, | 3724 | .cmpxchg_emulated = emulator_cmpxchg_emulated, |
3725 | .pio_in_emulated = emulator_pio_in_emulated, | ||
3726 | .pio_out_emulated = emulator_pio_out_emulated, | ||
3727 | .get_cached_descriptor = emulator_get_cached_descriptor, | ||
3728 | .set_cached_descriptor = emulator_set_cached_descriptor, | ||
3729 | .get_segment_selector = emulator_get_segment_selector, | ||
3730 | .set_segment_selector = emulator_set_segment_selector, | ||
3731 | .get_gdt = emulator_get_gdt, | ||
3732 | .get_cr = emulator_get_cr, | ||
3733 | .set_cr = emulator_set_cr, | ||
3734 | .cpl = emulator_get_cpl, | ||
3735 | .set_rflags = emulator_set_rflags, | ||
3371 | }; | 3736 | }; |
3372 | 3737 | ||
3373 | static void cache_all_regs(struct kvm_vcpu *vcpu) | 3738 | static void cache_all_regs(struct kvm_vcpu *vcpu) |
@@ -3398,14 +3763,14 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3398 | cache_all_regs(vcpu); | 3763 | cache_all_regs(vcpu); |
3399 | 3764 | ||
3400 | vcpu->mmio_is_write = 0; | 3765 | vcpu->mmio_is_write = 0; |
3401 | vcpu->arch.pio.string = 0; | ||
3402 | 3766 | ||
3403 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { | 3767 | if (!(emulation_type & EMULTYPE_NO_DECODE)) { |
3404 | int cs_db, cs_l; | 3768 | int cs_db, cs_l; |
3405 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); | 3769 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); |
3406 | 3770 | ||
3407 | vcpu->arch.emulate_ctxt.vcpu = vcpu; | 3771 | vcpu->arch.emulate_ctxt.vcpu = vcpu; |
3408 | vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu); | 3772 | vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); |
3773 | vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu); | ||
3409 | vcpu->arch.emulate_ctxt.mode = | 3774 | vcpu->arch.emulate_ctxt.mode = |
3410 | (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : | 3775 | (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : |
3411 | (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) | 3776 | (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) |
@@ -3414,6 +3779,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3414 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | 3779 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; |
3415 | 3780 | ||
3416 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); | 3781 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); |
3782 | trace_kvm_emulate_insn_start(vcpu); | ||
3417 | 3783 | ||
3418 | /* Only allow emulation of specific instructions on #UD | 3784 | /* Only allow emulation of specific instructions on #UD |
3419 | * (namely VMMCALL, sysenter, sysexit, syscall)*/ | 3785 | * (namely VMMCALL, sysenter, sysexit, syscall)*/ |
@@ -3446,6 +3812,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3446 | ++vcpu->stat.insn_emulation; | 3812 | ++vcpu->stat.insn_emulation; |
3447 | if (r) { | 3813 | if (r) { |
3448 | ++vcpu->stat.insn_emulation_fail; | 3814 | ++vcpu->stat.insn_emulation_fail; |
3815 | trace_kvm_emulate_insn_failed(vcpu); | ||
3449 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) | 3816 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) |
3450 | return EMULATE_DONE; | 3817 | return EMULATE_DONE; |
3451 | return EMULATE_FAIL; | 3818 | return EMULATE_FAIL; |
@@ -3457,16 +3824,20 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3457 | return EMULATE_DONE; | 3824 | return EMULATE_DONE; |
3458 | } | 3825 | } |
3459 | 3826 | ||
3827 | restart: | ||
3460 | r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); | 3828 | r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); |
3461 | shadow_mask = vcpu->arch.emulate_ctxt.interruptibility; | 3829 | shadow_mask = vcpu->arch.emulate_ctxt.interruptibility; |
3462 | 3830 | ||
3463 | if (r == 0) | 3831 | if (r == 0) |
3464 | kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); | 3832 | kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask); |
3465 | 3833 | ||
3466 | if (vcpu->arch.pio.string) | 3834 | if (vcpu->arch.pio.count) { |
3835 | if (!vcpu->arch.pio.in) | ||
3836 | vcpu->arch.pio.count = 0; | ||
3467 | return EMULATE_DO_MMIO; | 3837 | return EMULATE_DO_MMIO; |
3838 | } | ||
3468 | 3839 | ||
3469 | if ((r || vcpu->mmio_is_write) && run) { | 3840 | if (r || vcpu->mmio_is_write) { |
3470 | run->exit_reason = KVM_EXIT_MMIO; | 3841 | run->exit_reason = KVM_EXIT_MMIO; |
3471 | run->mmio.phys_addr = vcpu->mmio_phys_addr; | 3842 | run->mmio.phys_addr = vcpu->mmio_phys_addr; |
3472 | memcpy(run->mmio.data, vcpu->mmio_data, 8); | 3843 | memcpy(run->mmio.data, vcpu->mmio_data, 8); |
@@ -3476,222 +3847,41 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3476 | 3847 | ||
3477 | if (r) { | 3848 | if (r) { |
3478 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) | 3849 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) |
3479 | return EMULATE_DONE; | 3850 | goto done; |
3480 | if (!vcpu->mmio_needed) { | 3851 | if (!vcpu->mmio_needed) { |
3852 | ++vcpu->stat.insn_emulation_fail; | ||
3853 | trace_kvm_emulate_insn_failed(vcpu); | ||
3481 | kvm_report_emulation_failure(vcpu, "mmio"); | 3854 | kvm_report_emulation_failure(vcpu, "mmio"); |
3482 | return EMULATE_FAIL; | 3855 | return EMULATE_FAIL; |
3483 | } | 3856 | } |
3484 | return EMULATE_DO_MMIO; | 3857 | return EMULATE_DO_MMIO; |
3485 | } | 3858 | } |
3486 | 3859 | ||
3487 | kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); | ||
3488 | |||
3489 | if (vcpu->mmio_is_write) { | 3860 | if (vcpu->mmio_is_write) { |
3490 | vcpu->mmio_needed = 0; | 3861 | vcpu->mmio_needed = 0; |
3491 | return EMULATE_DO_MMIO; | 3862 | return EMULATE_DO_MMIO; |
3492 | } | 3863 | } |
3493 | 3864 | ||
3494 | return EMULATE_DONE; | 3865 | done: |
3495 | } | 3866 | if (vcpu->arch.exception.pending) |
3496 | EXPORT_SYMBOL_GPL(emulate_instruction); | 3867 | vcpu->arch.emulate_ctxt.restart = false; |
3497 | |||
3498 | static int pio_copy_data(struct kvm_vcpu *vcpu) | ||
3499 | { | ||
3500 | void *p = vcpu->arch.pio_data; | ||
3501 | gva_t q = vcpu->arch.pio.guest_gva; | ||
3502 | unsigned bytes; | ||
3503 | int ret; | ||
3504 | u32 error_code; | ||
3505 | |||
3506 | bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count; | ||
3507 | if (vcpu->arch.pio.in) | ||
3508 | ret = kvm_write_guest_virt(q, p, bytes, vcpu, &error_code); | ||
3509 | else | ||
3510 | ret = kvm_read_guest_virt(q, p, bytes, vcpu, &error_code); | ||
3511 | |||
3512 | if (ret == X86EMUL_PROPAGATE_FAULT) | ||
3513 | kvm_inject_page_fault(vcpu, q, error_code); | ||
3514 | |||
3515 | return ret; | ||
3516 | } | ||
3517 | |||
3518 | int complete_pio(struct kvm_vcpu *vcpu) | ||
3519 | { | ||
3520 | struct kvm_pio_request *io = &vcpu->arch.pio; | ||
3521 | long delta; | ||
3522 | int r; | ||
3523 | unsigned long val; | ||
3524 | |||
3525 | if (!io->string) { | ||
3526 | if (io->in) { | ||
3527 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); | ||
3528 | memcpy(&val, vcpu->arch.pio_data, io->size); | ||
3529 | kvm_register_write(vcpu, VCPU_REGS_RAX, val); | ||
3530 | } | ||
3531 | } else { | ||
3532 | if (io->in) { | ||
3533 | r = pio_copy_data(vcpu); | ||
3534 | if (r) | ||
3535 | goto out; | ||
3536 | } | ||
3537 | |||
3538 | delta = 1; | ||
3539 | if (io->rep) { | ||
3540 | delta *= io->cur_count; | ||
3541 | /* | ||
3542 | * The size of the register should really depend on | ||
3543 | * current address size. | ||
3544 | */ | ||
3545 | val = kvm_register_read(vcpu, VCPU_REGS_RCX); | ||
3546 | val -= delta; | ||
3547 | kvm_register_write(vcpu, VCPU_REGS_RCX, val); | ||
3548 | } | ||
3549 | if (io->down) | ||
3550 | delta = -delta; | ||
3551 | delta *= io->size; | ||
3552 | if (io->in) { | ||
3553 | val = kvm_register_read(vcpu, VCPU_REGS_RDI); | ||
3554 | val += delta; | ||
3555 | kvm_register_write(vcpu, VCPU_REGS_RDI, val); | ||
3556 | } else { | ||
3557 | val = kvm_register_read(vcpu, VCPU_REGS_RSI); | ||
3558 | val += delta; | ||
3559 | kvm_register_write(vcpu, VCPU_REGS_RSI, val); | ||
3560 | } | ||
3561 | } | ||
3562 | out: | ||
3563 | io->count -= io->cur_count; | ||
3564 | io->cur_count = 0; | ||
3565 | |||
3566 | return 0; | ||
3567 | } | ||
3568 | 3868 | ||
3569 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) | 3869 | if (vcpu->arch.emulate_ctxt.restart) |
3570 | { | 3870 | goto restart; |
3571 | /* TODO: String I/O for in kernel device */ | ||
3572 | int r; | ||
3573 | 3871 | ||
3574 | if (vcpu->arch.pio.in) | 3872 | return EMULATE_DONE; |
3575 | r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port, | ||
3576 | vcpu->arch.pio.size, pd); | ||
3577 | else | ||
3578 | r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, | ||
3579 | vcpu->arch.pio.port, vcpu->arch.pio.size, | ||
3580 | pd); | ||
3581 | return r; | ||
3582 | } | ||
3583 | |||
3584 | static int pio_string_write(struct kvm_vcpu *vcpu) | ||
3585 | { | ||
3586 | struct kvm_pio_request *io = &vcpu->arch.pio; | ||
3587 | void *pd = vcpu->arch.pio_data; | ||
3588 | int i, r = 0; | ||
3589 | |||
3590 | for (i = 0; i < io->cur_count; i++) { | ||
3591 | if (kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS, | ||
3592 | io->port, io->size, pd)) { | ||
3593 | r = -EOPNOTSUPP; | ||
3594 | break; | ||
3595 | } | ||
3596 | pd += io->size; | ||
3597 | } | ||
3598 | return r; | ||
3599 | } | ||
3600 | |||
3601 | int kvm_emulate_pio(struct kvm_vcpu *vcpu, int in, int size, unsigned port) | ||
3602 | { | ||
3603 | unsigned long val; | ||
3604 | |||
3605 | trace_kvm_pio(!in, port, size, 1); | ||
3606 | |||
3607 | vcpu->run->exit_reason = KVM_EXIT_IO; | ||
3608 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; | ||
3609 | vcpu->run->io.size = vcpu->arch.pio.size = size; | ||
3610 | vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; | ||
3611 | vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = 1; | ||
3612 | vcpu->run->io.port = vcpu->arch.pio.port = port; | ||
3613 | vcpu->arch.pio.in = in; | ||
3614 | vcpu->arch.pio.string = 0; | ||
3615 | vcpu->arch.pio.down = 0; | ||
3616 | vcpu->arch.pio.rep = 0; | ||
3617 | |||
3618 | if (!vcpu->arch.pio.in) { | ||
3619 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); | ||
3620 | memcpy(vcpu->arch.pio_data, &val, 4); | ||
3621 | } | ||
3622 | |||
3623 | if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { | ||
3624 | complete_pio(vcpu); | ||
3625 | return 1; | ||
3626 | } | ||
3627 | return 0; | ||
3628 | } | 3873 | } |
3629 | EXPORT_SYMBOL_GPL(kvm_emulate_pio); | 3874 | EXPORT_SYMBOL_GPL(emulate_instruction); |
3630 | 3875 | ||
3631 | int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in, | 3876 | int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) |
3632 | int size, unsigned long count, int down, | ||
3633 | gva_t address, int rep, unsigned port) | ||
3634 | { | 3877 | { |
3635 | unsigned now, in_page; | 3878 | unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX); |
3636 | int ret = 0; | 3879 | int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu); |
3637 | 3880 | /* do not return to emulator after return from userspace */ | |
3638 | trace_kvm_pio(!in, port, size, count); | 3881 | vcpu->arch.pio.count = 0; |
3639 | |||
3640 | vcpu->run->exit_reason = KVM_EXIT_IO; | ||
3641 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; | ||
3642 | vcpu->run->io.size = vcpu->arch.pio.size = size; | ||
3643 | vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; | ||
3644 | vcpu->run->io.count = vcpu->arch.pio.count = vcpu->arch.pio.cur_count = count; | ||
3645 | vcpu->run->io.port = vcpu->arch.pio.port = port; | ||
3646 | vcpu->arch.pio.in = in; | ||
3647 | vcpu->arch.pio.string = 1; | ||
3648 | vcpu->arch.pio.down = down; | ||
3649 | vcpu->arch.pio.rep = rep; | ||
3650 | |||
3651 | if (!count) { | ||
3652 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
3653 | return 1; | ||
3654 | } | ||
3655 | |||
3656 | if (!down) | ||
3657 | in_page = PAGE_SIZE - offset_in_page(address); | ||
3658 | else | ||
3659 | in_page = offset_in_page(address) + size; | ||
3660 | now = min(count, (unsigned long)in_page / size); | ||
3661 | if (!now) | ||
3662 | now = 1; | ||
3663 | if (down) { | ||
3664 | /* | ||
3665 | * String I/O in reverse. Yuck. Kill the guest, fix later. | ||
3666 | */ | ||
3667 | pr_unimpl(vcpu, "guest string pio down\n"); | ||
3668 | kvm_inject_gp(vcpu, 0); | ||
3669 | return 1; | ||
3670 | } | ||
3671 | vcpu->run->io.count = now; | ||
3672 | vcpu->arch.pio.cur_count = now; | ||
3673 | |||
3674 | if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count) | ||
3675 | kvm_x86_ops->skip_emulated_instruction(vcpu); | ||
3676 | |||
3677 | vcpu->arch.pio.guest_gva = address; | ||
3678 | |||
3679 | if (!vcpu->arch.pio.in) { | ||
3680 | /* string PIO write */ | ||
3681 | ret = pio_copy_data(vcpu); | ||
3682 | if (ret == X86EMUL_PROPAGATE_FAULT) | ||
3683 | return 1; | ||
3684 | if (ret == 0 && !pio_string_write(vcpu)) { | ||
3685 | complete_pio(vcpu); | ||
3686 | if (vcpu->arch.pio.count == 0) | ||
3687 | ret = 1; | ||
3688 | } | ||
3689 | } | ||
3690 | /* no string PIO read support yet */ | ||
3691 | |||
3692 | return ret; | 3882 | return ret; |
3693 | } | 3883 | } |
3694 | EXPORT_SYMBOL_GPL(kvm_emulate_pio_string); | 3884 | EXPORT_SYMBOL_GPL(kvm_fast_pio_out); |
3695 | 3885 | ||
3696 | static void bounce_off(void *info) | 3886 | static void bounce_off(void *info) |
3697 | { | 3887 | { |
@@ -4010,85 +4200,20 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu) | |||
4010 | return emulator_write_emulated(rip, instruction, 3, vcpu); | 4200 | return emulator_write_emulated(rip, instruction, 3, vcpu); |
4011 | } | 4201 | } |
4012 | 4202 | ||
4013 | static u64 mk_cr_64(u64 curr_cr, u32 new_val) | ||
4014 | { | ||
4015 | return (curr_cr & ~((1ULL << 32) - 1)) | new_val; | ||
4016 | } | ||
4017 | |||
4018 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) | 4203 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) |
4019 | { | 4204 | { |
4020 | struct descriptor_table dt = { limit, base }; | 4205 | struct desc_ptr dt = { limit, base }; |
4021 | 4206 | ||
4022 | kvm_x86_ops->set_gdt(vcpu, &dt); | 4207 | kvm_x86_ops->set_gdt(vcpu, &dt); |
4023 | } | 4208 | } |
4024 | 4209 | ||
4025 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) | 4210 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) |
4026 | { | 4211 | { |
4027 | struct descriptor_table dt = { limit, base }; | 4212 | struct desc_ptr dt = { limit, base }; |
4028 | 4213 | ||
4029 | kvm_x86_ops->set_idt(vcpu, &dt); | 4214 | kvm_x86_ops->set_idt(vcpu, &dt); |
4030 | } | 4215 | } |
4031 | 4216 | ||
4032 | void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, | ||
4033 | unsigned long *rflags) | ||
4034 | { | ||
4035 | kvm_lmsw(vcpu, msw); | ||
4036 | *rflags = kvm_get_rflags(vcpu); | ||
4037 | } | ||
4038 | |||
4039 | unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) | ||
4040 | { | ||
4041 | unsigned long value; | ||
4042 | |||
4043 | switch (cr) { | ||
4044 | case 0: | ||
4045 | value = kvm_read_cr0(vcpu); | ||
4046 | break; | ||
4047 | case 2: | ||
4048 | value = vcpu->arch.cr2; | ||
4049 | break; | ||
4050 | case 3: | ||
4051 | value = vcpu->arch.cr3; | ||
4052 | break; | ||
4053 | case 4: | ||
4054 | value = kvm_read_cr4(vcpu); | ||
4055 | break; | ||
4056 | case 8: | ||
4057 | value = kvm_get_cr8(vcpu); | ||
4058 | break; | ||
4059 | default: | ||
4060 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | ||
4061 | return 0; | ||
4062 | } | ||
4063 | |||
4064 | return value; | ||
4065 | } | ||
4066 | |||
4067 | void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, | ||
4068 | unsigned long *rflags) | ||
4069 | { | ||
4070 | switch (cr) { | ||
4071 | case 0: | ||
4072 | kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val)); | ||
4073 | *rflags = kvm_get_rflags(vcpu); | ||
4074 | break; | ||
4075 | case 2: | ||
4076 | vcpu->arch.cr2 = val; | ||
4077 | break; | ||
4078 | case 3: | ||
4079 | kvm_set_cr3(vcpu, val); | ||
4080 | break; | ||
4081 | case 4: | ||
4082 | kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); | ||
4083 | break; | ||
4084 | case 8: | ||
4085 | kvm_set_cr8(vcpu, val & 0xfUL); | ||
4086 | break; | ||
4087 | default: | ||
4088 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | ||
4089 | } | ||
4090 | } | ||
4091 | |||
4092 | static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) | 4217 | static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) |
4093 | { | 4218 | { |
4094 | struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; | 4219 | struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; |
@@ -4152,9 +4277,13 @@ int cpuid_maxphyaddr(struct kvm_vcpu *vcpu) | |||
4152 | { | 4277 | { |
4153 | struct kvm_cpuid_entry2 *best; | 4278 | struct kvm_cpuid_entry2 *best; |
4154 | 4279 | ||
4280 | best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0); | ||
4281 | if (!best || best->eax < 0x80000008) | ||
4282 | goto not_found; | ||
4155 | best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); | 4283 | best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); |
4156 | if (best) | 4284 | if (best) |
4157 | return best->eax & 0xff; | 4285 | return best->eax & 0xff; |
4286 | not_found: | ||
4158 | return 36; | 4287 | return 36; |
4159 | } | 4288 | } |
4160 | 4289 | ||
@@ -4268,6 +4397,9 @@ static void inject_pending_event(struct kvm_vcpu *vcpu) | |||
4268 | { | 4397 | { |
4269 | /* try to reinject previous events if any */ | 4398 | /* try to reinject previous events if any */ |
4270 | if (vcpu->arch.exception.pending) { | 4399 | if (vcpu->arch.exception.pending) { |
4400 | trace_kvm_inj_exception(vcpu->arch.exception.nr, | ||
4401 | vcpu->arch.exception.has_error_code, | ||
4402 | vcpu->arch.exception.error_code); | ||
4271 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, | 4403 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, |
4272 | vcpu->arch.exception.has_error_code, | 4404 | vcpu->arch.exception.has_error_code, |
4273 | vcpu->arch.exception.error_code); | 4405 | vcpu->arch.exception.error_code); |
@@ -4528,24 +4660,17 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
4528 | if (!irqchip_in_kernel(vcpu->kvm)) | 4660 | if (!irqchip_in_kernel(vcpu->kvm)) |
4529 | kvm_set_cr8(vcpu, kvm_run->cr8); | 4661 | kvm_set_cr8(vcpu, kvm_run->cr8); |
4530 | 4662 | ||
4531 | if (vcpu->arch.pio.cur_count) { | 4663 | if (vcpu->arch.pio.count || vcpu->mmio_needed || |
4532 | r = complete_pio(vcpu); | 4664 | vcpu->arch.emulate_ctxt.restart) { |
4533 | if (r) | 4665 | if (vcpu->mmio_needed) { |
4534 | goto out; | 4666 | memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); |
4535 | } | 4667 | vcpu->mmio_read_completed = 1; |
4536 | if (vcpu->mmio_needed) { | 4668 | vcpu->mmio_needed = 0; |
4537 | memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); | 4669 | } |
4538 | vcpu->mmio_read_completed = 1; | ||
4539 | vcpu->mmio_needed = 0; | ||
4540 | |||
4541 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 4670 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
4542 | r = emulate_instruction(vcpu, vcpu->arch.mmio_fault_cr2, 0, | 4671 | r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); |
4543 | EMULTYPE_NO_DECODE); | ||
4544 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); | 4672 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); |
4545 | if (r == EMULATE_DO_MMIO) { | 4673 | if (r == EMULATE_DO_MMIO) { |
4546 | /* | ||
4547 | * Read-modify-write. Back to userspace. | ||
4548 | */ | ||
4549 | r = 0; | 4674 | r = 0; |
4550 | goto out; | 4675 | goto out; |
4551 | } | 4676 | } |
@@ -4628,12 +4753,6 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
4628 | return 0; | 4753 | return 0; |
4629 | } | 4754 | } |
4630 | 4755 | ||
4631 | void kvm_get_segment(struct kvm_vcpu *vcpu, | ||
4632 | struct kvm_segment *var, int seg) | ||
4633 | { | ||
4634 | kvm_x86_ops->get_segment(vcpu, var, seg); | ||
4635 | } | ||
4636 | |||
4637 | void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) | 4756 | void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) |
4638 | { | 4757 | { |
4639 | struct kvm_segment cs; | 4758 | struct kvm_segment cs; |
@@ -4647,7 +4766,7 @@ EXPORT_SYMBOL_GPL(kvm_get_cs_db_l_bits); | |||
4647 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | 4766 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, |
4648 | struct kvm_sregs *sregs) | 4767 | struct kvm_sregs *sregs) |
4649 | { | 4768 | { |
4650 | struct descriptor_table dt; | 4769 | struct desc_ptr dt; |
4651 | 4770 | ||
4652 | vcpu_load(vcpu); | 4771 | vcpu_load(vcpu); |
4653 | 4772 | ||
@@ -4662,11 +4781,11 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | |||
4662 | kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); | 4781 | kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); |
4663 | 4782 | ||
4664 | kvm_x86_ops->get_idt(vcpu, &dt); | 4783 | kvm_x86_ops->get_idt(vcpu, &dt); |
4665 | sregs->idt.limit = dt.limit; | 4784 | sregs->idt.limit = dt.size; |
4666 | sregs->idt.base = dt.base; | 4785 | sregs->idt.base = dt.address; |
4667 | kvm_x86_ops->get_gdt(vcpu, &dt); | 4786 | kvm_x86_ops->get_gdt(vcpu, &dt); |
4668 | sregs->gdt.limit = dt.limit; | 4787 | sregs->gdt.limit = dt.size; |
4669 | sregs->gdt.base = dt.base; | 4788 | sregs->gdt.base = dt.address; |
4670 | 4789 | ||
4671 | sregs->cr0 = kvm_read_cr0(vcpu); | 4790 | sregs->cr0 = kvm_read_cr0(vcpu); |
4672 | sregs->cr2 = vcpu->arch.cr2; | 4791 | sregs->cr2 = vcpu->arch.cr2; |
@@ -4705,559 +4824,33 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | |||
4705 | return 0; | 4824 | return 0; |
4706 | } | 4825 | } |
4707 | 4826 | ||
4708 | static void kvm_set_segment(struct kvm_vcpu *vcpu, | 4827 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, |
4709 | struct kvm_segment *var, int seg) | 4828 | bool has_error_code, u32 error_code) |
4710 | { | ||
4711 | kvm_x86_ops->set_segment(vcpu, var, seg); | ||
4712 | } | ||
4713 | |||
4714 | static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, | ||
4715 | struct kvm_segment *kvm_desct) | ||
4716 | { | ||
4717 | kvm_desct->base = get_desc_base(seg_desc); | ||
4718 | kvm_desct->limit = get_desc_limit(seg_desc); | ||
4719 | if (seg_desc->g) { | ||
4720 | kvm_desct->limit <<= 12; | ||
4721 | kvm_desct->limit |= 0xfff; | ||
4722 | } | ||
4723 | kvm_desct->selector = selector; | ||
4724 | kvm_desct->type = seg_desc->type; | ||
4725 | kvm_desct->present = seg_desc->p; | ||
4726 | kvm_desct->dpl = seg_desc->dpl; | ||
4727 | kvm_desct->db = seg_desc->d; | ||
4728 | kvm_desct->s = seg_desc->s; | ||
4729 | kvm_desct->l = seg_desc->l; | ||
4730 | kvm_desct->g = seg_desc->g; | ||
4731 | kvm_desct->avl = seg_desc->avl; | ||
4732 | if (!selector) | ||
4733 | kvm_desct->unusable = 1; | ||
4734 | else | ||
4735 | kvm_desct->unusable = 0; | ||
4736 | kvm_desct->padding = 0; | ||
4737 | } | ||
4738 | |||
4739 | static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, | ||
4740 | u16 selector, | ||
4741 | struct descriptor_table *dtable) | ||
4742 | { | ||
4743 | if (selector & 1 << 2) { | ||
4744 | struct kvm_segment kvm_seg; | ||
4745 | |||
4746 | kvm_get_segment(vcpu, &kvm_seg, VCPU_SREG_LDTR); | ||
4747 | |||
4748 | if (kvm_seg.unusable) | ||
4749 | dtable->limit = 0; | ||
4750 | else | ||
4751 | dtable->limit = kvm_seg.limit; | ||
4752 | dtable->base = kvm_seg.base; | ||
4753 | } | ||
4754 | else | ||
4755 | kvm_x86_ops->get_gdt(vcpu, dtable); | ||
4756 | } | ||
4757 | |||
4758 | /* allowed just for 8 bytes segments */ | ||
4759 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | ||
4760 | struct desc_struct *seg_desc) | ||
4761 | { | ||
4762 | struct descriptor_table dtable; | ||
4763 | u16 index = selector >> 3; | ||
4764 | int ret; | ||
4765 | u32 err; | ||
4766 | gva_t addr; | ||
4767 | |||
4768 | get_segment_descriptor_dtable(vcpu, selector, &dtable); | ||
4769 | |||
4770 | if (dtable.limit < index * 8 + 7) { | ||
4771 | kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); | ||
4772 | return X86EMUL_PROPAGATE_FAULT; | ||
4773 | } | ||
4774 | addr = dtable.base + index * 8; | ||
4775 | ret = kvm_read_guest_virt_system(addr, seg_desc, sizeof(*seg_desc), | ||
4776 | vcpu, &err); | ||
4777 | if (ret == X86EMUL_PROPAGATE_FAULT) | ||
4778 | kvm_inject_page_fault(vcpu, addr, err); | ||
4779 | |||
4780 | return ret; | ||
4781 | } | ||
4782 | |||
4783 | /* allowed just for 8 bytes segments */ | ||
4784 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | ||
4785 | struct desc_struct *seg_desc) | ||
4786 | { | ||
4787 | struct descriptor_table dtable; | ||
4788 | u16 index = selector >> 3; | ||
4789 | |||
4790 | get_segment_descriptor_dtable(vcpu, selector, &dtable); | ||
4791 | |||
4792 | if (dtable.limit < index * 8 + 7) | ||
4793 | return 1; | ||
4794 | return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu, NULL); | ||
4795 | } | ||
4796 | |||
4797 | static gpa_t get_tss_base_addr_write(struct kvm_vcpu *vcpu, | ||
4798 | struct desc_struct *seg_desc) | ||
4799 | { | ||
4800 | u32 base_addr = get_desc_base(seg_desc); | ||
4801 | |||
4802 | return kvm_mmu_gva_to_gpa_write(vcpu, base_addr, NULL); | ||
4803 | } | ||
4804 | |||
4805 | static gpa_t get_tss_base_addr_read(struct kvm_vcpu *vcpu, | ||
4806 | struct desc_struct *seg_desc) | ||
4807 | { | ||
4808 | u32 base_addr = get_desc_base(seg_desc); | ||
4809 | |||
4810 | return kvm_mmu_gva_to_gpa_read(vcpu, base_addr, NULL); | ||
4811 | } | ||
4812 | |||
4813 | static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg) | ||
4814 | { | ||
4815 | struct kvm_segment kvm_seg; | ||
4816 | |||
4817 | kvm_get_segment(vcpu, &kvm_seg, seg); | ||
4818 | return kvm_seg.selector; | ||
4819 | } | ||
4820 | |||
4821 | static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg) | ||
4822 | { | ||
4823 | struct kvm_segment segvar = { | ||
4824 | .base = selector << 4, | ||
4825 | .limit = 0xffff, | ||
4826 | .selector = selector, | ||
4827 | .type = 3, | ||
4828 | .present = 1, | ||
4829 | .dpl = 3, | ||
4830 | .db = 0, | ||
4831 | .s = 1, | ||
4832 | .l = 0, | ||
4833 | .g = 0, | ||
4834 | .avl = 0, | ||
4835 | .unusable = 0, | ||
4836 | }; | ||
4837 | kvm_x86_ops->set_segment(vcpu, &segvar, seg); | ||
4838 | return X86EMUL_CONTINUE; | ||
4839 | } | ||
4840 | |||
4841 | static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg) | ||
4842 | { | 4829 | { |
4843 | return (seg != VCPU_SREG_LDTR) && | 4830 | int cs_db, cs_l, ret; |
4844 | (seg != VCPU_SREG_TR) && | 4831 | cache_all_regs(vcpu); |
4845 | (kvm_get_rflags(vcpu) & X86_EFLAGS_VM); | ||
4846 | } | ||
4847 | |||
4848 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, int seg) | ||
4849 | { | ||
4850 | struct kvm_segment kvm_seg; | ||
4851 | struct desc_struct seg_desc; | ||
4852 | u8 dpl, rpl, cpl; | ||
4853 | unsigned err_vec = GP_VECTOR; | ||
4854 | u32 err_code = 0; | ||
4855 | bool null_selector = !(selector & ~0x3); /* 0000-0003 are null */ | ||
4856 | int ret; | ||
4857 | 4832 | ||
4858 | if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu)) | 4833 | kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); |
4859 | return kvm_load_realmode_segment(vcpu, selector, seg); | ||
4860 | 4834 | ||
4861 | /* NULL selector is not valid for TR, CS and SS */ | 4835 | vcpu->arch.emulate_ctxt.vcpu = vcpu; |
4862 | if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) | 4836 | vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu); |
4863 | && null_selector) | 4837 | vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu); |
4864 | goto exception; | 4838 | vcpu->arch.emulate_ctxt.mode = |
4839 | (!is_protmode(vcpu)) ? X86EMUL_MODE_REAL : | ||
4840 | (vcpu->arch.emulate_ctxt.eflags & X86_EFLAGS_VM) | ||
4841 | ? X86EMUL_MODE_VM86 : cs_l | ||
4842 | ? X86EMUL_MODE_PROT64 : cs_db | ||
4843 | ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | ||
4865 | 4844 | ||
4866 | /* TR should be in GDT only */ | 4845 | ret = emulator_task_switch(&vcpu->arch.emulate_ctxt, &emulate_ops, |
4867 | if (seg == VCPU_SREG_TR && (selector & (1 << 2))) | 4846 | tss_selector, reason, has_error_code, |
4868 | goto exception; | 4847 | error_code); |
4869 | 4848 | ||
4870 | ret = load_guest_segment_descriptor(vcpu, selector, &seg_desc); | ||
4871 | if (ret) | 4849 | if (ret) |
4872 | return ret; | 4850 | return EMULATE_FAIL; |
4873 | |||
4874 | seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg); | ||
4875 | |||
4876 | if (null_selector) { /* for NULL selector skip all following checks */ | ||
4877 | kvm_seg.unusable = 1; | ||
4878 | goto load; | ||
4879 | } | ||
4880 | |||
4881 | err_code = selector & 0xfffc; | ||
4882 | err_vec = GP_VECTOR; | ||
4883 | |||
4884 | /* can't load system descriptor into segment selecor */ | ||
4885 | if (seg <= VCPU_SREG_GS && !kvm_seg.s) | ||
4886 | goto exception; | ||
4887 | |||
4888 | if (!kvm_seg.present) { | ||
4889 | err_vec = (seg == VCPU_SREG_SS) ? SS_VECTOR : NP_VECTOR; | ||
4890 | goto exception; | ||
4891 | } | ||
4892 | |||
4893 | rpl = selector & 3; | ||
4894 | dpl = kvm_seg.dpl; | ||
4895 | cpl = kvm_x86_ops->get_cpl(vcpu); | ||
4896 | |||
4897 | switch (seg) { | ||
4898 | case VCPU_SREG_SS: | ||
4899 | /* | ||
4900 | * segment is not a writable data segment or segment | ||
4901 | * selector's RPL != CPL or segment selector's RPL != CPL | ||
4902 | */ | ||
4903 | if (rpl != cpl || (kvm_seg.type & 0xa) != 0x2 || dpl != cpl) | ||
4904 | goto exception; | ||
4905 | break; | ||
4906 | case VCPU_SREG_CS: | ||
4907 | if (!(kvm_seg.type & 8)) | ||
4908 | goto exception; | ||
4909 | |||
4910 | if (kvm_seg.type & 4) { | ||
4911 | /* conforming */ | ||
4912 | if (dpl > cpl) | ||
4913 | goto exception; | ||
4914 | } else { | ||
4915 | /* nonconforming */ | ||
4916 | if (rpl > cpl || dpl != cpl) | ||
4917 | goto exception; | ||
4918 | } | ||
4919 | /* CS(RPL) <- CPL */ | ||
4920 | selector = (selector & 0xfffc) | cpl; | ||
4921 | break; | ||
4922 | case VCPU_SREG_TR: | ||
4923 | if (kvm_seg.s || (kvm_seg.type != 1 && kvm_seg.type != 9)) | ||
4924 | goto exception; | ||
4925 | break; | ||
4926 | case VCPU_SREG_LDTR: | ||
4927 | if (kvm_seg.s || kvm_seg.type != 2) | ||
4928 | goto exception; | ||
4929 | break; | ||
4930 | default: /* DS, ES, FS, or GS */ | ||
4931 | /* | ||
4932 | * segment is not a data or readable code segment or | ||
4933 | * ((segment is a data or nonconforming code segment) | ||
4934 | * and (both RPL and CPL > DPL)) | ||
4935 | */ | ||
4936 | if ((kvm_seg.type & 0xa) == 0x8 || | ||
4937 | (((kvm_seg.type & 0xc) != 0xc) && (rpl > dpl && cpl > dpl))) | ||
4938 | goto exception; | ||
4939 | break; | ||
4940 | } | ||
4941 | |||
4942 | if (!kvm_seg.unusable && kvm_seg.s) { | ||
4943 | /* mark segment as accessed */ | ||
4944 | kvm_seg.type |= 1; | ||
4945 | seg_desc.type |= 1; | ||
4946 | save_guest_segment_descriptor(vcpu, selector, &seg_desc); | ||
4947 | } | ||
4948 | load: | ||
4949 | kvm_set_segment(vcpu, &kvm_seg, seg); | ||
4950 | return X86EMUL_CONTINUE; | ||
4951 | exception: | ||
4952 | kvm_queue_exception_e(vcpu, err_vec, err_code); | ||
4953 | return X86EMUL_PROPAGATE_FAULT; | ||
4954 | } | ||
4955 | |||
4956 | static void save_state_to_tss32(struct kvm_vcpu *vcpu, | ||
4957 | struct tss_segment_32 *tss) | ||
4958 | { | ||
4959 | tss->cr3 = vcpu->arch.cr3; | ||
4960 | tss->eip = kvm_rip_read(vcpu); | ||
4961 | tss->eflags = kvm_get_rflags(vcpu); | ||
4962 | tss->eax = kvm_register_read(vcpu, VCPU_REGS_RAX); | ||
4963 | tss->ecx = kvm_register_read(vcpu, VCPU_REGS_RCX); | ||
4964 | tss->edx = kvm_register_read(vcpu, VCPU_REGS_RDX); | ||
4965 | tss->ebx = kvm_register_read(vcpu, VCPU_REGS_RBX); | ||
4966 | tss->esp = kvm_register_read(vcpu, VCPU_REGS_RSP); | ||
4967 | tss->ebp = kvm_register_read(vcpu, VCPU_REGS_RBP); | ||
4968 | tss->esi = kvm_register_read(vcpu, VCPU_REGS_RSI); | ||
4969 | tss->edi = kvm_register_read(vcpu, VCPU_REGS_RDI); | ||
4970 | tss->es = get_segment_selector(vcpu, VCPU_SREG_ES); | ||
4971 | tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS); | ||
4972 | tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS); | ||
4973 | tss->ds = get_segment_selector(vcpu, VCPU_SREG_DS); | ||
4974 | tss->fs = get_segment_selector(vcpu, VCPU_SREG_FS); | ||
4975 | tss->gs = get_segment_selector(vcpu, VCPU_SREG_GS); | ||
4976 | tss->ldt_selector = get_segment_selector(vcpu, VCPU_SREG_LDTR); | ||
4977 | } | ||
4978 | |||
4979 | static void kvm_load_segment_selector(struct kvm_vcpu *vcpu, u16 sel, int seg) | ||
4980 | { | ||
4981 | struct kvm_segment kvm_seg; | ||
4982 | kvm_get_segment(vcpu, &kvm_seg, seg); | ||
4983 | kvm_seg.selector = sel; | ||
4984 | kvm_set_segment(vcpu, &kvm_seg, seg); | ||
4985 | } | ||
4986 | |||
4987 | static int load_state_from_tss32(struct kvm_vcpu *vcpu, | ||
4988 | struct tss_segment_32 *tss) | ||
4989 | { | ||
4990 | kvm_set_cr3(vcpu, tss->cr3); | ||
4991 | |||
4992 | kvm_rip_write(vcpu, tss->eip); | ||
4993 | kvm_set_rflags(vcpu, tss->eflags | 2); | ||
4994 | |||
4995 | kvm_register_write(vcpu, VCPU_REGS_RAX, tss->eax); | ||
4996 | kvm_register_write(vcpu, VCPU_REGS_RCX, tss->ecx); | ||
4997 | kvm_register_write(vcpu, VCPU_REGS_RDX, tss->edx); | ||
4998 | kvm_register_write(vcpu, VCPU_REGS_RBX, tss->ebx); | ||
4999 | kvm_register_write(vcpu, VCPU_REGS_RSP, tss->esp); | ||
5000 | kvm_register_write(vcpu, VCPU_REGS_RBP, tss->ebp); | ||
5001 | kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi); | ||
5002 | kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi); | ||
5003 | |||
5004 | /* | ||
5005 | * SDM says that segment selectors are loaded before segment | ||
5006 | * descriptors | ||
5007 | */ | ||
5008 | kvm_load_segment_selector(vcpu, tss->ldt_selector, VCPU_SREG_LDTR); | ||
5009 | kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); | ||
5010 | kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); | ||
5011 | kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); | ||
5012 | kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); | ||
5013 | kvm_load_segment_selector(vcpu, tss->fs, VCPU_SREG_FS); | ||
5014 | kvm_load_segment_selector(vcpu, tss->gs, VCPU_SREG_GS); | ||
5015 | |||
5016 | /* | ||
5017 | * Now load segment descriptors. If fault happenes at this stage | ||
5018 | * it is handled in a context of new task | ||
5019 | */ | ||
5020 | if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, VCPU_SREG_LDTR)) | ||
5021 | return 1; | ||
5022 | |||
5023 | if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) | ||
5024 | return 1; | ||
5025 | |||
5026 | if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) | ||
5027 | return 1; | ||
5028 | |||
5029 | if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) | ||
5030 | return 1; | ||
5031 | |||
5032 | if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) | ||
5033 | return 1; | ||
5034 | |||
5035 | if (kvm_load_segment_descriptor(vcpu, tss->fs, VCPU_SREG_FS)) | ||
5036 | return 1; | ||
5037 | |||
5038 | if (kvm_load_segment_descriptor(vcpu, tss->gs, VCPU_SREG_GS)) | ||
5039 | return 1; | ||
5040 | return 0; | ||
5041 | } | ||
5042 | |||
5043 | static void save_state_to_tss16(struct kvm_vcpu *vcpu, | ||
5044 | struct tss_segment_16 *tss) | ||
5045 | { | ||
5046 | tss->ip = kvm_rip_read(vcpu); | ||
5047 | tss->flag = kvm_get_rflags(vcpu); | ||
5048 | tss->ax = kvm_register_read(vcpu, VCPU_REGS_RAX); | ||
5049 | tss->cx = kvm_register_read(vcpu, VCPU_REGS_RCX); | ||
5050 | tss->dx = kvm_register_read(vcpu, VCPU_REGS_RDX); | ||
5051 | tss->bx = kvm_register_read(vcpu, VCPU_REGS_RBX); | ||
5052 | tss->sp = kvm_register_read(vcpu, VCPU_REGS_RSP); | ||
5053 | tss->bp = kvm_register_read(vcpu, VCPU_REGS_RBP); | ||
5054 | tss->si = kvm_register_read(vcpu, VCPU_REGS_RSI); | ||
5055 | tss->di = kvm_register_read(vcpu, VCPU_REGS_RDI); | ||
5056 | |||
5057 | tss->es = get_segment_selector(vcpu, VCPU_SREG_ES); | ||
5058 | tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS); | ||
5059 | tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS); | ||
5060 | tss->ds = get_segment_selector(vcpu, VCPU_SREG_DS); | ||
5061 | tss->ldt = get_segment_selector(vcpu, VCPU_SREG_LDTR); | ||
5062 | } | ||
5063 | |||
5064 | static int load_state_from_tss16(struct kvm_vcpu *vcpu, | ||
5065 | struct tss_segment_16 *tss) | ||
5066 | { | ||
5067 | kvm_rip_write(vcpu, tss->ip); | ||
5068 | kvm_set_rflags(vcpu, tss->flag | 2); | ||
5069 | kvm_register_write(vcpu, VCPU_REGS_RAX, tss->ax); | ||
5070 | kvm_register_write(vcpu, VCPU_REGS_RCX, tss->cx); | ||
5071 | kvm_register_write(vcpu, VCPU_REGS_RDX, tss->dx); | ||
5072 | kvm_register_write(vcpu, VCPU_REGS_RBX, tss->bx); | ||
5073 | kvm_register_write(vcpu, VCPU_REGS_RSP, tss->sp); | ||
5074 | kvm_register_write(vcpu, VCPU_REGS_RBP, tss->bp); | ||
5075 | kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si); | ||
5076 | kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di); | ||
5077 | |||
5078 | /* | ||
5079 | * SDM says that segment selectors are loaded before segment | ||
5080 | * descriptors | ||
5081 | */ | ||
5082 | kvm_load_segment_selector(vcpu, tss->ldt, VCPU_SREG_LDTR); | ||
5083 | kvm_load_segment_selector(vcpu, tss->es, VCPU_SREG_ES); | ||
5084 | kvm_load_segment_selector(vcpu, tss->cs, VCPU_SREG_CS); | ||
5085 | kvm_load_segment_selector(vcpu, tss->ss, VCPU_SREG_SS); | ||
5086 | kvm_load_segment_selector(vcpu, tss->ds, VCPU_SREG_DS); | ||
5087 | |||
5088 | /* | ||
5089 | * Now load segment descriptors. If fault happenes at this stage | ||
5090 | * it is handled in a context of new task | ||
5091 | */ | ||
5092 | if (kvm_load_segment_descriptor(vcpu, tss->ldt, VCPU_SREG_LDTR)) | ||
5093 | return 1; | ||
5094 | |||
5095 | if (kvm_load_segment_descriptor(vcpu, tss->es, VCPU_SREG_ES)) | ||
5096 | return 1; | ||
5097 | |||
5098 | if (kvm_load_segment_descriptor(vcpu, tss->cs, VCPU_SREG_CS)) | ||
5099 | return 1; | ||
5100 | |||
5101 | if (kvm_load_segment_descriptor(vcpu, tss->ss, VCPU_SREG_SS)) | ||
5102 | return 1; | ||
5103 | |||
5104 | if (kvm_load_segment_descriptor(vcpu, tss->ds, VCPU_SREG_DS)) | ||
5105 | return 1; | ||
5106 | return 0; | ||
5107 | } | ||
5108 | |||
5109 | static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector, | ||
5110 | u16 old_tss_sel, u32 old_tss_base, | ||
5111 | struct desc_struct *nseg_desc) | ||
5112 | { | ||
5113 | struct tss_segment_16 tss_segment_16; | ||
5114 | int ret = 0; | ||
5115 | |||
5116 | if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16, | ||
5117 | sizeof tss_segment_16)) | ||
5118 | goto out; | ||
5119 | |||
5120 | save_state_to_tss16(vcpu, &tss_segment_16); | ||
5121 | |||
5122 | if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16, | ||
5123 | sizeof tss_segment_16)) | ||
5124 | goto out; | ||
5125 | |||
5126 | if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), | ||
5127 | &tss_segment_16, sizeof tss_segment_16)) | ||
5128 | goto out; | ||
5129 | |||
5130 | if (old_tss_sel != 0xffff) { | ||
5131 | tss_segment_16.prev_task_link = old_tss_sel; | ||
5132 | |||
5133 | if (kvm_write_guest(vcpu->kvm, | ||
5134 | get_tss_base_addr_write(vcpu, nseg_desc), | ||
5135 | &tss_segment_16.prev_task_link, | ||
5136 | sizeof tss_segment_16.prev_task_link)) | ||
5137 | goto out; | ||
5138 | } | ||
5139 | |||
5140 | if (load_state_from_tss16(vcpu, &tss_segment_16)) | ||
5141 | goto out; | ||
5142 | |||
5143 | ret = 1; | ||
5144 | out: | ||
5145 | return ret; | ||
5146 | } | ||
5147 | |||
5148 | static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector, | ||
5149 | u16 old_tss_sel, u32 old_tss_base, | ||
5150 | struct desc_struct *nseg_desc) | ||
5151 | { | ||
5152 | struct tss_segment_32 tss_segment_32; | ||
5153 | int ret = 0; | ||
5154 | |||
5155 | if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32, | ||
5156 | sizeof tss_segment_32)) | ||
5157 | goto out; | ||
5158 | |||
5159 | save_state_to_tss32(vcpu, &tss_segment_32); | ||
5160 | |||
5161 | if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32, | ||
5162 | sizeof tss_segment_32)) | ||
5163 | goto out; | ||
5164 | |||
5165 | if (kvm_read_guest(vcpu->kvm, get_tss_base_addr_read(vcpu, nseg_desc), | ||
5166 | &tss_segment_32, sizeof tss_segment_32)) | ||
5167 | goto out; | ||
5168 | |||
5169 | if (old_tss_sel != 0xffff) { | ||
5170 | tss_segment_32.prev_task_link = old_tss_sel; | ||
5171 | |||
5172 | if (kvm_write_guest(vcpu->kvm, | ||
5173 | get_tss_base_addr_write(vcpu, nseg_desc), | ||
5174 | &tss_segment_32.prev_task_link, | ||
5175 | sizeof tss_segment_32.prev_task_link)) | ||
5176 | goto out; | ||
5177 | } | ||
5178 | |||
5179 | if (load_state_from_tss32(vcpu, &tss_segment_32)) | ||
5180 | goto out; | ||
5181 | |||
5182 | ret = 1; | ||
5183 | out: | ||
5184 | return ret; | ||
5185 | } | ||
5186 | |||
5187 | int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) | ||
5188 | { | ||
5189 | struct kvm_segment tr_seg; | ||
5190 | struct desc_struct cseg_desc; | ||
5191 | struct desc_struct nseg_desc; | ||
5192 | int ret = 0; | ||
5193 | u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR); | ||
5194 | u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR); | ||
5195 | |||
5196 | old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL); | ||
5197 | |||
5198 | /* FIXME: Handle errors. Failure to read either TSS or their | ||
5199 | * descriptors should generate a pagefault. | ||
5200 | */ | ||
5201 | if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)) | ||
5202 | goto out; | ||
5203 | |||
5204 | if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc)) | ||
5205 | goto out; | ||
5206 | |||
5207 | if (reason != TASK_SWITCH_IRET) { | ||
5208 | int cpl; | ||
5209 | |||
5210 | cpl = kvm_x86_ops->get_cpl(vcpu); | ||
5211 | if ((tss_selector & 3) > nseg_desc.dpl || cpl > nseg_desc.dpl) { | ||
5212 | kvm_queue_exception_e(vcpu, GP_VECTOR, 0); | ||
5213 | return 1; | ||
5214 | } | ||
5215 | } | ||
5216 | 4851 | ||
5217 | if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) { | 4852 | kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags); |
5218 | kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); | 4853 | return EMULATE_DONE; |
5219 | return 1; | ||
5220 | } | ||
5221 | |||
5222 | if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { | ||
5223 | cseg_desc.type &= ~(1 << 1); //clear the B flag | ||
5224 | save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc); | ||
5225 | } | ||
5226 | |||
5227 | if (reason == TASK_SWITCH_IRET) { | ||
5228 | u32 eflags = kvm_get_rflags(vcpu); | ||
5229 | kvm_set_rflags(vcpu, eflags & ~X86_EFLAGS_NT); | ||
5230 | } | ||
5231 | |||
5232 | /* set back link to prev task only if NT bit is set in eflags | ||
5233 | note that old_tss_sel is not used afetr this point */ | ||
5234 | if (reason != TASK_SWITCH_CALL && reason != TASK_SWITCH_GATE) | ||
5235 | old_tss_sel = 0xffff; | ||
5236 | |||
5237 | if (nseg_desc.type & 8) | ||
5238 | ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_sel, | ||
5239 | old_tss_base, &nseg_desc); | ||
5240 | else | ||
5241 | ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_sel, | ||
5242 | old_tss_base, &nseg_desc); | ||
5243 | |||
5244 | if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) { | ||
5245 | u32 eflags = kvm_get_rflags(vcpu); | ||
5246 | kvm_set_rflags(vcpu, eflags | X86_EFLAGS_NT); | ||
5247 | } | ||
5248 | |||
5249 | if (reason != TASK_SWITCH_IRET) { | ||
5250 | nseg_desc.type |= (1 << 1); | ||
5251 | save_guest_segment_descriptor(vcpu, tss_selector, | ||
5252 | &nseg_desc); | ||
5253 | } | ||
5254 | |||
5255 | kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0(vcpu) | X86_CR0_TS); | ||
5256 | seg_desct_to_kvm_desct(&nseg_desc, tss_selector, &tr_seg); | ||
5257 | tr_seg.type = 11; | ||
5258 | kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR); | ||
5259 | out: | ||
5260 | return ret; | ||
5261 | } | 4854 | } |
5262 | EXPORT_SYMBOL_GPL(kvm_task_switch); | 4855 | EXPORT_SYMBOL_GPL(kvm_task_switch); |
5263 | 4856 | ||
@@ -5266,15 +4859,15 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
5266 | { | 4859 | { |
5267 | int mmu_reset_needed = 0; | 4860 | int mmu_reset_needed = 0; |
5268 | int pending_vec, max_bits; | 4861 | int pending_vec, max_bits; |
5269 | struct descriptor_table dt; | 4862 | struct desc_ptr dt; |
5270 | 4863 | ||
5271 | vcpu_load(vcpu); | 4864 | vcpu_load(vcpu); |
5272 | 4865 | ||
5273 | dt.limit = sregs->idt.limit; | 4866 | dt.size = sregs->idt.limit; |
5274 | dt.base = sregs->idt.base; | 4867 | dt.address = sregs->idt.base; |
5275 | kvm_x86_ops->set_idt(vcpu, &dt); | 4868 | kvm_x86_ops->set_idt(vcpu, &dt); |
5276 | dt.limit = sregs->gdt.limit; | 4869 | dt.size = sregs->gdt.limit; |
5277 | dt.base = sregs->gdt.base; | 4870 | dt.address = sregs->gdt.base; |
5278 | kvm_x86_ops->set_gdt(vcpu, &dt); | 4871 | kvm_x86_ops->set_gdt(vcpu, &dt); |
5279 | 4872 | ||
5280 | vcpu->arch.cr2 = sregs->cr2; | 4873 | vcpu->arch.cr2 = sregs->cr2; |
@@ -5373,11 +4966,9 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, | |||
5373 | vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); | 4966 | vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK); |
5374 | } | 4967 | } |
5375 | 4968 | ||
5376 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) { | 4969 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |
5377 | vcpu->arch.singlestep_cs = | 4970 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) + |
5378 | get_segment_selector(vcpu, VCPU_SREG_CS); | 4971 | get_segment_base(vcpu, VCPU_SREG_CS); |
5379 | vcpu->arch.singlestep_rip = kvm_rip_read(vcpu); | ||
5380 | } | ||
5381 | 4972 | ||
5382 | /* | 4973 | /* |
5383 | * Trigger an rflags update that will inject or remove the trace | 4974 | * Trigger an rflags update that will inject or remove the trace |
@@ -5868,13 +5459,22 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
5868 | return kvm_x86_ops->interrupt_allowed(vcpu); | 5459 | return kvm_x86_ops->interrupt_allowed(vcpu); |
5869 | } | 5460 | } |
5870 | 5461 | ||
5462 | bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip) | ||
5463 | { | ||
5464 | unsigned long current_rip = kvm_rip_read(vcpu) + | ||
5465 | get_segment_base(vcpu, VCPU_SREG_CS); | ||
5466 | |||
5467 | return current_rip == linear_rip; | ||
5468 | } | ||
5469 | EXPORT_SYMBOL_GPL(kvm_is_linear_rip); | ||
5470 | |||
5871 | unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) | 5471 | unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu) |
5872 | { | 5472 | { |
5873 | unsigned long rflags; | 5473 | unsigned long rflags; |
5874 | 5474 | ||
5875 | rflags = kvm_x86_ops->get_rflags(vcpu); | 5475 | rflags = kvm_x86_ops->get_rflags(vcpu); |
5876 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | 5476 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) |
5877 | rflags &= ~(unsigned long)(X86_EFLAGS_TF | X86_EFLAGS_RF); | 5477 | rflags &= ~X86_EFLAGS_TF; |
5878 | return rflags; | 5478 | return rflags; |
5879 | } | 5479 | } |
5880 | EXPORT_SYMBOL_GPL(kvm_get_rflags); | 5480 | EXPORT_SYMBOL_GPL(kvm_get_rflags); |
@@ -5882,10 +5482,8 @@ EXPORT_SYMBOL_GPL(kvm_get_rflags); | |||
5882 | void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 5482 | void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
5883 | { | 5483 | { |
5884 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && | 5484 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP && |
5885 | vcpu->arch.singlestep_cs == | 5485 | kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip)) |
5886 | get_segment_selector(vcpu, VCPU_SREG_CS) && | 5486 | rflags |= X86_EFLAGS_TF; |
5887 | vcpu->arch.singlestep_rip == kvm_rip_read(vcpu)) | ||
5888 | rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF; | ||
5889 | kvm_x86_ops->set_rflags(vcpu, rflags); | 5487 | kvm_x86_ops->set_rflags(vcpu, rflags); |
5890 | } | 5488 | } |
5891 | EXPORT_SYMBOL_GPL(kvm_set_rflags); | 5489 | EXPORT_SYMBOL_GPL(kvm_set_rflags); |
@@ -5901,3 +5499,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_vmexit_inject); | |||
5901 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit); | 5499 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intr_vmexit); |
5902 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga); | 5500 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga); |
5903 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit); | 5501 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit); |
5502 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts); | ||
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 7e59dc1d3fc2..2bdf628066bd 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1, | |||
115 | local_irq_save(flags); | 115 | local_irq_save(flags); |
116 | if (lguest_data.hcall_status[next_call] != 0xFF) { | 116 | if (lguest_data.hcall_status[next_call] != 0xFF) { |
117 | /* Table full, so do normal hcall which will flush table. */ | 117 | /* Table full, so do normal hcall which will flush table. */ |
118 | kvm_hypercall4(call, arg1, arg2, arg3, arg4); | 118 | hcall(call, arg1, arg2, arg3, arg4); |
119 | } else { | 119 | } else { |
120 | lguest_data.hcalls[next_call].arg0 = call; | 120 | lguest_data.hcalls[next_call].arg0 = call; |
121 | lguest_data.hcalls[next_call].arg1 = arg1; | 121 | lguest_data.hcalls[next_call].arg1 = arg1; |
@@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1, | |||
145 | * So, when we're in lazy mode, we call async_hcall() to store the call for | 145 | * So, when we're in lazy mode, we call async_hcall() to store the call for |
146 | * future processing: | 146 | * future processing: |
147 | */ | 147 | */ |
148 | static void lazy_hcall1(unsigned long call, | 148 | static void lazy_hcall1(unsigned long call, unsigned long arg1) |
149 | unsigned long arg1) | ||
150 | { | 149 | { |
151 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | 150 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) |
152 | kvm_hypercall1(call, arg1); | 151 | hcall(call, arg1, 0, 0, 0); |
153 | else | 152 | else |
154 | async_hcall(call, arg1, 0, 0, 0); | 153 | async_hcall(call, arg1, 0, 0, 0); |
155 | } | 154 | } |
156 | 155 | ||
157 | /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/ | 156 | /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/ |
158 | static void lazy_hcall2(unsigned long call, | 157 | static void lazy_hcall2(unsigned long call, |
159 | unsigned long arg1, | 158 | unsigned long arg1, |
160 | unsigned long arg2) | 159 | unsigned long arg2) |
161 | { | 160 | { |
162 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | 161 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) |
163 | kvm_hypercall2(call, arg1, arg2); | 162 | hcall(call, arg1, arg2, 0, 0); |
164 | else | 163 | else |
165 | async_hcall(call, arg1, arg2, 0, 0); | 164 | async_hcall(call, arg1, arg2, 0, 0); |
166 | } | 165 | } |
167 | 166 | ||
168 | static void lazy_hcall3(unsigned long call, | 167 | static void lazy_hcall3(unsigned long call, |
169 | unsigned long arg1, | 168 | unsigned long arg1, |
170 | unsigned long arg2, | 169 | unsigned long arg2, |
171 | unsigned long arg3) | 170 | unsigned long arg3) |
172 | { | 171 | { |
173 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | 172 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) |
174 | kvm_hypercall3(call, arg1, arg2, arg3); | 173 | hcall(call, arg1, arg2, arg3, 0); |
175 | else | 174 | else |
176 | async_hcall(call, arg1, arg2, arg3, 0); | 175 | async_hcall(call, arg1, arg2, arg3, 0); |
177 | } | 176 | } |
178 | 177 | ||
179 | #ifdef CONFIG_X86_PAE | 178 | #ifdef CONFIG_X86_PAE |
180 | static void lazy_hcall4(unsigned long call, | 179 | static void lazy_hcall4(unsigned long call, |
181 | unsigned long arg1, | 180 | unsigned long arg1, |
182 | unsigned long arg2, | 181 | unsigned long arg2, |
183 | unsigned long arg3, | 182 | unsigned long arg3, |
184 | unsigned long arg4) | 183 | unsigned long arg4) |
185 | { | 184 | { |
186 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | 185 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) |
187 | kvm_hypercall4(call, arg1, arg2, arg3, arg4); | 186 | hcall(call, arg1, arg2, arg3, arg4); |
188 | else | 187 | else |
189 | async_hcall(call, arg1, arg2, arg3, arg4); | 188 | async_hcall(call, arg1, arg2, arg3, arg4); |
190 | } | 189 | } |
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call, | |||
196 | :*/ | 195 | :*/ |
197 | static void lguest_leave_lazy_mmu_mode(void) | 196 | static void lguest_leave_lazy_mmu_mode(void) |
198 | { | 197 | { |
199 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); | 198 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
200 | paravirt_leave_lazy_mmu(); | 199 | paravirt_leave_lazy_mmu(); |
201 | } | 200 | } |
202 | 201 | ||
203 | static void lguest_end_context_switch(struct task_struct *next) | 202 | static void lguest_end_context_switch(struct task_struct *next) |
204 | { | 203 | { |
205 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); | 204 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
206 | paravirt_end_context_switch(next); | 205 | paravirt_end_context_switch(next); |
207 | } | 206 | } |
208 | 207 | ||
@@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt, | |||
286 | /* Keep the local copy up to date. */ | 285 | /* Keep the local copy up to date. */ |
287 | native_write_idt_entry(dt, entrynum, g); | 286 | native_write_idt_entry(dt, entrynum, g); |
288 | /* Tell Host about this new entry. */ | 287 | /* Tell Host about this new entry. */ |
289 | kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); | 288 | hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0); |
290 | } | 289 | } |
291 | 290 | ||
292 | /* | 291 | /* |
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc) | |||
300 | struct desc_struct *idt = (void *)desc->address; | 299 | struct desc_struct *idt = (void *)desc->address; |
301 | 300 | ||
302 | for (i = 0; i < (desc->size+1)/8; i++) | 301 | for (i = 0; i < (desc->size+1)/8; i++) |
303 | kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); | 302 | hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0); |
304 | } | 303 | } |
305 | 304 | ||
306 | /* | 305 | /* |
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc) | |||
321 | struct desc_struct *gdt = (void *)desc->address; | 320 | struct desc_struct *gdt = (void *)desc->address; |
322 | 321 | ||
323 | for (i = 0; i < (desc->size+1)/8; i++) | 322 | for (i = 0; i < (desc->size+1)/8; i++) |
324 | kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b); | 323 | hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0); |
325 | } | 324 | } |
326 | 325 | ||
327 | /* | 326 | /* |
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | |||
334 | { | 333 | { |
335 | native_write_gdt_entry(dt, entrynum, desc, type); | 334 | native_write_gdt_entry(dt, entrynum, desc, type); |
336 | /* Tell Host about this new entry. */ | 335 | /* Tell Host about this new entry. */ |
337 | kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum, | 336 | hcall(LHCALL_LOAD_GDT_ENTRY, entrynum, |
338 | dt[entrynum].a, dt[entrynum].b); | 337 | dt[entrynum].a, dt[entrynum].b, 0); |
339 | } | 338 | } |
340 | 339 | ||
341 | /* | 340 | /* |
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta, | |||
931 | } | 930 | } |
932 | 931 | ||
933 | /* Please wake us this far in the future. */ | 932 | /* Please wake us this far in the future. */ |
934 | kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); | 933 | hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0); |
935 | return 0; | 934 | return 0; |
936 | } | 935 | } |
937 | 936 | ||
@@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode, | |||
942 | case CLOCK_EVT_MODE_UNUSED: | 941 | case CLOCK_EVT_MODE_UNUSED: |
943 | case CLOCK_EVT_MODE_SHUTDOWN: | 942 | case CLOCK_EVT_MODE_SHUTDOWN: |
944 | /* A 0 argument shuts the clock down. */ | 943 | /* A 0 argument shuts the clock down. */ |
945 | kvm_hypercall0(LHCALL_SET_CLOCKEVENT); | 944 | hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0); |
946 | break; | 945 | break; |
947 | case CLOCK_EVT_MODE_ONESHOT: | 946 | case CLOCK_EVT_MODE_ONESHOT: |
948 | /* This is what we expect. */ | 947 | /* This is what we expect. */ |
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void) | |||
1100 | /* STOP! Until an interrupt comes in. */ | 1099 | /* STOP! Until an interrupt comes in. */ |
1101 | static void lguest_safe_halt(void) | 1100 | static void lguest_safe_halt(void) |
1102 | { | 1101 | { |
1103 | kvm_hypercall0(LHCALL_HALT); | 1102 | hcall(LHCALL_HALT, 0, 0, 0, 0); |
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | /* | 1105 | /* |
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void) | |||
1112 | */ | 1111 | */ |
1113 | static void lguest_power_off(void) | 1112 | static void lguest_power_off(void) |
1114 | { | 1113 | { |
1115 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"), | 1114 | hcall(LHCALL_SHUTDOWN, __pa("Power down"), |
1116 | LGUEST_SHUTDOWN_POWEROFF); | 1115 | LGUEST_SHUTDOWN_POWEROFF, 0, 0); |
1117 | } | 1116 | } |
1118 | 1117 | ||
1119 | /* | 1118 | /* |
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void) | |||
1123 | */ | 1122 | */ |
1124 | static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) | 1123 | static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) |
1125 | { | 1124 | { |
1126 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF); | 1125 | hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0); |
1127 | /* The hcall won't return, but to keep gcc happy, we're "done". */ | 1126 | /* The hcall won't return, but to keep gcc happy, we're "done". */ |
1128 | return NOTIFY_DONE; | 1127 | return NOTIFY_DONE; |
1129 | } | 1128 | } |
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) | |||
1162 | len = sizeof(scratch) - 1; | 1161 | len = sizeof(scratch) - 1; |
1163 | scratch[len] = '\0'; | 1162 | scratch[len] = '\0'; |
1164 | memcpy(scratch, buf, len); | 1163 | memcpy(scratch, buf, len); |
1165 | kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); | 1164 | hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0); |
1166 | 1165 | ||
1167 | /* This routine returns the number of bytes actually written. */ | 1166 | /* This routine returns the number of bytes actually written. */ |
1168 | return len; | 1167 | return len; |
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) | |||
1174 | */ | 1173 | */ |
1175 | static void lguest_restart(char *reason) | 1174 | static void lguest_restart(char *reason) |
1176 | { | 1175 | { |
1177 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART); | 1176 | hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0); |
1178 | } | 1177 | } |
1179 | 1178 | ||
1180 | /*G:050 | 1179 | /*G:050 |
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 27eac0faee48..4f420c2f2d55 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
@@ -32,7 +32,7 @@ ENTRY(lguest_entry) | |||
32 | */ | 32 | */ |
33 | movl $LHCALL_LGUEST_INIT, %eax | 33 | movl $LHCALL_LGUEST_INIT, %eax |
34 | movl $lguest_data - __PAGE_OFFSET, %ebx | 34 | movl $lguest_data - __PAGE_OFFSET, %ebx |
35 | .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */ | 35 | int $LGUEST_TRAP_ENTRY |
36 | 36 | ||
37 | /* Set up the initial stack so we can run C code. */ | 37 | /* Set up the initial stack so we can run C code. */ |
38 | movl $(init_thread_union+THREAD_SIZE),%esp | 38 | movl $(init_thread_union+THREAD_SIZE),%esp |
diff --git a/block/Kconfig b/block/Kconfig index 62a5921321cd..f9e89f4d94bb 100644 --- a/block/Kconfig +++ b/block/Kconfig | |||
@@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY | |||
78 | Protection. If in doubt, say N. | 78 | Protection. If in doubt, say N. |
79 | 79 | ||
80 | config BLK_CGROUP | 80 | config BLK_CGROUP |
81 | tristate | 81 | tristate "Block cgroup support" |
82 | depends on CGROUPS | 82 | depends on CGROUPS |
83 | depends on CFQ_GROUP_IOSCHED | ||
83 | default n | 84 | default n |
84 | ---help--- | 85 | ---help--- |
85 | Generic block IO controller cgroup interface. This is the common | 86 | Generic block IO controller cgroup interface. This is the common |
diff --git a/block/blk-settings.c b/block/blk-settings.c index d9a9db5f0a2b..f5ed5a1187ba 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
9 | #include <linux/bootmem.h> /* for max_pfn/max_low_pfn */ | 9 | #include <linux/bootmem.h> /* for max_pfn/max_low_pfn */ |
10 | #include <linux/gcd.h> | 10 | #include <linux/gcd.h> |
11 | #include <linux/lcm.h> | ||
11 | #include <linux/jiffies.h> | 12 | #include <linux/jiffies.h> |
12 | #include <linux/gfp.h> | 13 | #include <linux/gfp.h> |
13 | 14 | ||
@@ -462,16 +463,6 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) | |||
462 | } | 463 | } |
463 | EXPORT_SYMBOL(blk_queue_stack_limits); | 464 | EXPORT_SYMBOL(blk_queue_stack_limits); |
464 | 465 | ||
465 | static unsigned int lcm(unsigned int a, unsigned int b) | ||
466 | { | ||
467 | if (a && b) | ||
468 | return (a * b) / gcd(a, b); | ||
469 | else if (b) | ||
470 | return b; | ||
471 | |||
472 | return a; | ||
473 | } | ||
474 | |||
475 | /** | 466 | /** |
476 | * blk_stack_limits - adjust queue_limits for stacked devices | 467 | * blk_stack_limits - adjust queue_limits for stacked devices |
477 | * @t: the stacking driver limits (top device) | 468 | * @t: the stacking driver limits (top device) |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index c2b821fa324a..306759bbdf1b 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -107,6 +107,19 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page) | |||
107 | return queue_var_show(max_sectors_kb, (page)); | 107 | return queue_var_show(max_sectors_kb, (page)); |
108 | } | 108 | } |
109 | 109 | ||
110 | static ssize_t queue_max_segments_show(struct request_queue *q, char *page) | ||
111 | { | ||
112 | return queue_var_show(queue_max_segments(q), (page)); | ||
113 | } | ||
114 | |||
115 | static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) | ||
116 | { | ||
117 | if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | ||
118 | return queue_var_show(queue_max_segment_size(q), (page)); | ||
119 | |||
120 | return queue_var_show(PAGE_CACHE_SIZE, (page)); | ||
121 | } | ||
122 | |||
110 | static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) | 123 | static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) |
111 | { | 124 | { |
112 | return queue_var_show(queue_logical_block_size(q), page); | 125 | return queue_var_show(queue_logical_block_size(q), page); |
@@ -281,6 +294,16 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = { | |||
281 | .show = queue_max_hw_sectors_show, | 294 | .show = queue_max_hw_sectors_show, |
282 | }; | 295 | }; |
283 | 296 | ||
297 | static struct queue_sysfs_entry queue_max_segments_entry = { | ||
298 | .attr = {.name = "max_segments", .mode = S_IRUGO }, | ||
299 | .show = queue_max_segments_show, | ||
300 | }; | ||
301 | |||
302 | static struct queue_sysfs_entry queue_max_segment_size_entry = { | ||
303 | .attr = {.name = "max_segment_size", .mode = S_IRUGO }, | ||
304 | .show = queue_max_segment_size_show, | ||
305 | }; | ||
306 | |||
284 | static struct queue_sysfs_entry queue_iosched_entry = { | 307 | static struct queue_sysfs_entry queue_iosched_entry = { |
285 | .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, | 308 | .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, |
286 | .show = elv_iosched_show, | 309 | .show = elv_iosched_show, |
@@ -356,6 +379,8 @@ static struct attribute *default_attrs[] = { | |||
356 | &queue_ra_entry.attr, | 379 | &queue_ra_entry.attr, |
357 | &queue_max_hw_sectors_entry.attr, | 380 | &queue_max_hw_sectors_entry.attr, |
358 | &queue_max_sectors_entry.attr, | 381 | &queue_max_sectors_entry.attr, |
382 | &queue_max_segments_entry.attr, | ||
383 | &queue_max_segment_size_entry.attr, | ||
359 | &queue_iosched_entry.attr, | 384 | &queue_iosched_entry.attr, |
360 | &queue_hw_sector_size_entry.attr, | 385 | &queue_hw_sector_size_entry.attr, |
361 | &queue_logical_block_size_entry.attr, | 386 | &queue_logical_block_size_entry.attr, |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index fc98a48554fd..838834be115b 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -48,6 +48,7 @@ static const int cfq_hist_divisor = 4; | |||
48 | #define CFQ_SERVICE_SHIFT 12 | 48 | #define CFQ_SERVICE_SHIFT 12 |
49 | 49 | ||
50 | #define CFQQ_SEEK_THR (sector_t)(8 * 100) | 50 | #define CFQQ_SEEK_THR (sector_t)(8 * 100) |
51 | #define CFQQ_CLOSE_THR (sector_t)(8 * 1024) | ||
51 | #define CFQQ_SECT_THR_NONROT (sector_t)(2 * 32) | 52 | #define CFQQ_SECT_THR_NONROT (sector_t)(2 * 32) |
52 | #define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8) | 53 | #define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8) |
53 | 54 | ||
@@ -948,6 +949,11 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) | |||
948 | unsigned int major, minor; | 949 | unsigned int major, minor; |
949 | 950 | ||
950 | cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key)); | 951 | cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key)); |
952 | if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { | ||
953 | sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); | ||
954 | cfqg->blkg.dev = MKDEV(major, minor); | ||
955 | goto done; | ||
956 | } | ||
951 | if (cfqg || !create) | 957 | if (cfqg || !create) |
952 | goto done; | 958 | goto done; |
953 | 959 | ||
@@ -1518,7 +1524,8 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, | |||
1518 | struct cfq_queue *cfqq) | 1524 | struct cfq_queue *cfqq) |
1519 | { | 1525 | { |
1520 | if (cfqq) { | 1526 | if (cfqq) { |
1521 | cfq_log_cfqq(cfqd, cfqq, "set_active"); | 1527 | cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d", |
1528 | cfqd->serving_prio, cfqd->serving_type); | ||
1522 | cfqq->slice_start = 0; | 1529 | cfqq->slice_start = 0; |
1523 | cfqq->dispatch_start = jiffies; | 1530 | cfqq->dispatch_start = jiffies; |
1524 | cfqq->allocated_slice = 0; | 1531 | cfqq->allocated_slice = 0; |
@@ -1661,9 +1668,9 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, | |||
1661 | } | 1668 | } |
1662 | 1669 | ||
1663 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 1670 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
1664 | struct request *rq, bool for_preempt) | 1671 | struct request *rq) |
1665 | { | 1672 | { |
1666 | return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR; | 1673 | return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR; |
1667 | } | 1674 | } |
1668 | 1675 | ||
1669 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | 1676 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, |
@@ -1690,7 +1697,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
1690 | * will contain the closest sector. | 1697 | * will contain the closest sector. |
1691 | */ | 1698 | */ |
1692 | __cfqq = rb_entry(parent, struct cfq_queue, p_node); | 1699 | __cfqq = rb_entry(parent, struct cfq_queue, p_node); |
1693 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) | 1700 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) |
1694 | return __cfqq; | 1701 | return __cfqq; |
1695 | 1702 | ||
1696 | if (blk_rq_pos(__cfqq->next_rq) < sector) | 1703 | if (blk_rq_pos(__cfqq->next_rq) < sector) |
@@ -1701,7 +1708,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
1701 | return NULL; | 1708 | return NULL; |
1702 | 1709 | ||
1703 | __cfqq = rb_entry(node, struct cfq_queue, p_node); | 1710 | __cfqq = rb_entry(node, struct cfq_queue, p_node); |
1704 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) | 1711 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) |
1705 | return __cfqq; | 1712 | return __cfqq; |
1706 | 1713 | ||
1707 | return NULL; | 1714 | return NULL; |
@@ -1722,6 +1729,8 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, | |||
1722 | { | 1729 | { |
1723 | struct cfq_queue *cfqq; | 1730 | struct cfq_queue *cfqq; |
1724 | 1731 | ||
1732 | if (cfq_class_idle(cur_cfqq)) | ||
1733 | return NULL; | ||
1725 | if (!cfq_cfqq_sync(cur_cfqq)) | 1734 | if (!cfq_cfqq_sync(cur_cfqq)) |
1726 | return NULL; | 1735 | return NULL; |
1727 | if (CFQQ_SEEKY(cur_cfqq)) | 1736 | if (CFQQ_SEEKY(cur_cfqq)) |
@@ -1788,7 +1797,11 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
1788 | * Otherwise, we do only if they are the last ones | 1797 | * Otherwise, we do only if they are the last ones |
1789 | * in their service tree. | 1798 | * in their service tree. |
1790 | */ | 1799 | */ |
1791 | return service_tree->count == 1 && cfq_cfqq_sync(cfqq); | 1800 | if (service_tree->count == 1 && cfq_cfqq_sync(cfqq)) |
1801 | return 1; | ||
1802 | cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d", | ||
1803 | service_tree->count); | ||
1804 | return 0; | ||
1792 | } | 1805 | } |
1793 | 1806 | ||
1794 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) | 1807 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) |
@@ -1833,8 +1846,11 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1833 | * time slice. | 1846 | * time slice. |
1834 | */ | 1847 | */ |
1835 | if (sample_valid(cic->ttime_samples) && | 1848 | if (sample_valid(cic->ttime_samples) && |
1836 | (cfqq->slice_end - jiffies < cic->ttime_mean)) | 1849 | (cfqq->slice_end - jiffies < cic->ttime_mean)) { |
1850 | cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d", | ||
1851 | cic->ttime_mean); | ||
1837 | return; | 1852 | return; |
1853 | } | ||
1838 | 1854 | ||
1839 | cfq_mark_cfqq_wait_request(cfqq); | 1855 | cfq_mark_cfqq_wait_request(cfqq); |
1840 | 1856 | ||
@@ -2042,6 +2058,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) | |||
2042 | slice = max(slice, 2 * cfqd->cfq_slice_idle); | 2058 | slice = max(slice, 2 * cfqd->cfq_slice_idle); |
2043 | 2059 | ||
2044 | slice = max_t(unsigned, slice, CFQ_MIN_TT); | 2060 | slice = max_t(unsigned, slice, CFQ_MIN_TT); |
2061 | cfq_log(cfqd, "workload slice:%d", slice); | ||
2045 | cfqd->workload_expires = jiffies + slice; | 2062 | cfqd->workload_expires = jiffies + slice; |
2046 | cfqd->noidle_tree_requires_idle = false; | 2063 | cfqd->noidle_tree_requires_idle = false; |
2047 | } | 2064 | } |
@@ -2189,10 +2206,13 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd) | |||
2189 | struct cfq_queue *cfqq; | 2206 | struct cfq_queue *cfqq; |
2190 | int dispatched = 0; | 2207 | int dispatched = 0; |
2191 | 2208 | ||
2192 | while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) | 2209 | /* Expire the timeslice of the current active queue first */ |
2210 | cfq_slice_expired(cfqd, 0); | ||
2211 | while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) { | ||
2212 | __cfq_set_active_queue(cfqd, cfqq); | ||
2193 | dispatched += __cfq_forced_dispatch_cfqq(cfqq); | 2213 | dispatched += __cfq_forced_dispatch_cfqq(cfqq); |
2214 | } | ||
2194 | 2215 | ||
2195 | cfq_slice_expired(cfqd, 0); | ||
2196 | BUG_ON(cfqd->busy_queues); | 2216 | BUG_ON(cfqd->busy_queues); |
2197 | 2217 | ||
2198 | cfq_log(cfqd, "forced_dispatch=%d", dispatched); | 2218 | cfq_log(cfqd, "forced_dispatch=%d", dispatched); |
@@ -3104,7 +3124,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
3104 | * if this request is as-good as one we would expect from the | 3124 | * if this request is as-good as one we would expect from the |
3105 | * current cfqq, let it preempt | 3125 | * current cfqq, let it preempt |
3106 | */ | 3126 | */ |
3107 | if (cfq_rq_close(cfqd, cfqq, rq, true)) | 3127 | if (cfq_rq_close(cfqd, cfqq, rq)) |
3108 | return true; | 3128 | return true; |
3109 | 3129 | ||
3110 | return false; | 3130 | return false; |
@@ -3308,6 +3328,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
3308 | if (cfq_should_wait_busy(cfqd, cfqq)) { | 3328 | if (cfq_should_wait_busy(cfqd, cfqq)) { |
3309 | cfqq->slice_end = jiffies + cfqd->cfq_slice_idle; | 3329 | cfqq->slice_end = jiffies + cfqd->cfq_slice_idle; |
3310 | cfq_mark_cfqq_wait_busy(cfqq); | 3330 | cfq_mark_cfqq_wait_busy(cfqq); |
3331 | cfq_log_cfqq(cfqd, cfqq, "will busy wait"); | ||
3311 | } | 3332 | } |
3312 | 3333 | ||
3313 | /* | 3334 | /* |
diff --git a/block/elevator.c b/block/elevator.c index df75676f6671..76e3702d5381 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -154,7 +154,7 @@ static struct elevator_type *elevator_get(const char *name) | |||
154 | 154 | ||
155 | spin_unlock(&elv_list_lock); | 155 | spin_unlock(&elv_list_lock); |
156 | 156 | ||
157 | sprintf(elv, "%s-iosched", name); | 157 | snprintf(elv, sizeof(elv), "%s-iosched", name); |
158 | 158 | ||
159 | request_module("%s", elv); | 159 | request_module("%s", elv); |
160 | spin_lock(&elv_list_lock); | 160 | spin_lock(&elv_list_lock); |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 837de669743a..78c55508aff5 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
117 | if (ACPI_FAILURE(status)) | 117 | if (ACPI_FAILURE(status)) |
118 | return_ACPI_STATUS(status); | 118 | return_ACPI_STATUS(status); |
119 | 119 | ||
120 | /* Mark wake-enabled or HW enable, or both */ | 120 | /* Clear the GPE (of stale events), then enable it */ |
121 | 121 | status = acpi_hw_clear_gpe(gpe_event_info); | |
122 | if (gpe_event_info->runtime_count) { | 122 | if (ACPI_FAILURE(status)) |
123 | /* Clear the GPE (of stale events), then enable it */ | 123 | return_ACPI_STATUS(status); |
124 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
125 | if (ACPI_FAILURE(status)) | ||
126 | return_ACPI_STATUS(status); | ||
127 | |||
128 | /* Enable the requested runtime GPE */ | ||
129 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); | ||
130 | } | ||
131 | 124 | ||
132 | return_ACPI_STATUS(AE_OK); | 125 | /* Enable the requested GPE */ |
126 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); | ||
127 | return_ACPI_STATUS(status); | ||
133 | } | 128 | } |
134 | 129 | ||
135 | /******************************************************************************* | 130 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index edf62bf5b266..2fbfe51fb141 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -468,6 +468,23 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
468 | 468 | ||
469 | acpi_ut_add_reference(obj_desc->field.region_obj); | 469 | acpi_ut_add_reference(obj_desc->field.region_obj); |
470 | 470 | ||
471 | /* allow full data read from EC address space */ | ||
472 | if (obj_desc->field.region_obj->region.space_id == | ||
473 | ACPI_ADR_SPACE_EC) { | ||
474 | if (obj_desc->common_field.bit_length > 8) { | ||
475 | unsigned width = | ||
476 | ACPI_ROUND_BITS_UP_TO_BYTES( | ||
477 | obj_desc->common_field.bit_length); | ||
478 | // access_bit_width is u8, don't overflow it | ||
479 | if (width > 8) | ||
480 | width = 8; | ||
481 | obj_desc->common_field.access_byte_width = | ||
482 | width; | ||
483 | obj_desc->common_field.access_bit_width = | ||
484 | 8 * width; | ||
485 | } | ||
486 | } | ||
487 | |||
471 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 488 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
472 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", | 489 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", |
473 | obj_desc->field.start_field_bit_offset, | 490 | obj_desc->field.start_field_bit_offset, |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 5717bd300869..3026e3fa83ef 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -568,13 +568,13 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
568 | result = acpi_battery_get_status(battery); | 568 | result = acpi_battery_get_status(battery); |
569 | if (result) | 569 | if (result) |
570 | return result; | 570 | return result; |
571 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
572 | if (!acpi_battery_present(battery)) { | 571 | if (!acpi_battery_present(battery)) { |
572 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
573 | sysfs_remove_battery(battery); | 573 | sysfs_remove_battery(battery); |
574 | #endif | ||
574 | battery->update_time = 0; | 575 | battery->update_time = 0; |
575 | return 0; | 576 | return 0; |
576 | } | 577 | } |
577 | #endif | ||
578 | if (!battery->update_time || | 578 | if (!battery->update_time || |
579 | old_present != acpi_battery_present(battery)) { | 579 | old_present != acpi_battery_present(battery)) { |
580 | result = acpi_battery_get_info(battery); | 580 | result = acpi_battery_get_info(battery); |
@@ -880,7 +880,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
880 | #ifdef CONFIG_ACPI_SYSFS_POWER | 880 | #ifdef CONFIG_ACPI_SYSFS_POWER |
881 | /* acpi_battery_update could remove power_supply object */ | 881 | /* acpi_battery_update could remove power_supply object */ |
882 | if (battery->bat.dev) | 882 | if (battery->bat.dev) |
883 | kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); | 883 | power_supply_changed(&battery->bat); |
884 | #endif | 884 | #endif |
885 | } | 885 | } |
886 | 886 | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index a9c429c5d50f..3fe29e992be8 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -1026,13 +1026,10 @@ static int dock_remove(struct dock_station *ds) | |||
1026 | static acpi_status | 1026 | static acpi_status |
1027 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) | 1027 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) |
1028 | { | 1028 | { |
1029 | acpi_status status = AE_OK; | ||
1030 | |||
1031 | if (is_dock(handle)) | 1029 | if (is_dock(handle)) |
1032 | if (dock_add(handle) >= 0) | 1030 | dock_add(handle); |
1033 | status = AE_CTRL_TERMINATE; | ||
1034 | 1031 | ||
1035 | return status; | 1032 | return AE_OK; |
1036 | } | 1033 | } |
1037 | 1034 | ||
1038 | static acpi_status | 1035 | static acpi_status |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 35ba2547f544..f2234db85da0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -629,12 +629,12 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
629 | 629 | ||
630 | static acpi_status | 630 | static acpi_status |
631 | acpi_ec_space_handler(u32 function, acpi_physical_address address, | 631 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
632 | u32 bits, u64 *value, | 632 | u32 bits, u64 *value64, |
633 | void *handler_context, void *region_context) | 633 | void *handler_context, void *region_context) |
634 | { | 634 | { |
635 | struct acpi_ec *ec = handler_context; | 635 | struct acpi_ec *ec = handler_context; |
636 | int result = 0, i; | 636 | int result = 0, i, bytes = bits / 8; |
637 | u8 temp = 0; | 637 | u8 *value = (u8 *)value64; |
638 | 638 | ||
639 | if ((address > 0xFF) || !value || !handler_context) | 639 | if ((address > 0xFF) || !value || !handler_context) |
640 | return AE_BAD_PARAMETER; | 640 | return AE_BAD_PARAMETER; |
@@ -642,32 +642,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
642 | if (function != ACPI_READ && function != ACPI_WRITE) | 642 | if (function != ACPI_READ && function != ACPI_WRITE) |
643 | return AE_BAD_PARAMETER; | 643 | return AE_BAD_PARAMETER; |
644 | 644 | ||
645 | if (bits != 8 && acpi_strict) | 645 | if (EC_FLAGS_MSI || bits > 8) |
646 | return AE_BAD_PARAMETER; | ||
647 | |||
648 | if (EC_FLAGS_MSI) | ||
649 | acpi_ec_burst_enable(ec); | 646 | acpi_ec_burst_enable(ec); |
650 | 647 | ||
651 | if (function == ACPI_READ) { | 648 | for (i = 0; i < bytes; ++i, ++address, ++value) |
652 | result = acpi_ec_read(ec, address, &temp); | 649 | result = (function == ACPI_READ) ? |
653 | *value = temp; | 650 | acpi_ec_read(ec, address, value) : |
654 | } else { | 651 | acpi_ec_write(ec, address, *value); |
655 | temp = 0xff & (*value); | ||
656 | result = acpi_ec_write(ec, address, temp); | ||
657 | } | ||
658 | |||
659 | for (i = 8; unlikely(bits - i > 0); i += 8) { | ||
660 | ++address; | ||
661 | if (function == ACPI_READ) { | ||
662 | result = acpi_ec_read(ec, address, &temp); | ||
663 | (*value) |= ((u64)temp) << i; | ||
664 | } else { | ||
665 | temp = 0xff & ((*value) >> i); | ||
666 | result = acpi_ec_write(ec, address, temp); | ||
667 | } | ||
668 | } | ||
669 | 652 | ||
670 | if (EC_FLAGS_MSI) | 653 | if (EC_FLAGS_MSI || bits > 8) |
671 | acpi_ec_burst_disable(ec); | 654 | acpi_ec_burst_disable(ec); |
672 | 655 | ||
673 | switch (result) { | 656 | switch (result) { |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index b8725461d887..b0337d314604 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -61,8 +61,10 @@ int node_to_pxm(int node) | |||
61 | 61 | ||
62 | void __acpi_map_pxm_to_node(int pxm, int node) | 62 | void __acpi_map_pxm_to_node(int pxm, int node) |
63 | { | 63 | { |
64 | pxm_to_node_map[pxm] = node; | 64 | if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) |
65 | node_to_pxm_map[node] = pxm; | 65 | pxm_to_node_map[pxm] = node; |
66 | if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node]) | ||
67 | node_to_pxm_map[node] = pxm; | ||
66 | } | 68 | } |
67 | 69 | ||
68 | int acpi_map_pxm_to_node(int pxm) | 70 | int acpi_map_pxm_to_node(int pxm) |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 8e6d8665f0ae..7594f65800cf 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
758 | queue = hp ? kacpi_hotplug_wq : | 758 | queue = hp ? kacpi_hotplug_wq : |
759 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); | 759 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); |
760 | dpc->wait = hp ? 1 : 0; | 760 | dpc->wait = hp ? 1 : 0; |
761 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 761 | |
762 | if (queue == kacpi_hotplug_wq) | ||
763 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
764 | else if (queue == kacpi_notify_wq) | ||
765 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
766 | else | ||
767 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
768 | |||
762 | ret = queue_work(queue, &dpc->work); | 769 | ret = queue_work(queue, &dpc->work); |
763 | 770 | ||
764 | if (!ret) { | 771 | if (!ret) { |
@@ -1151,16 +1158,10 @@ int acpi_check_resource_conflict(const struct resource *res) | |||
1151 | 1158 | ||
1152 | if (clash) { | 1159 | if (clash) { |
1153 | if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { | 1160 | if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { |
1154 | printk("%sACPI: %s resource %s [0x%llx-0x%llx]" | 1161 | printk(KERN_WARNING "ACPI: resource %s %pR" |
1155 | " conflicts with ACPI region %s" | 1162 | " conflicts with ACPI region %s %pR\n", |
1156 | " [0x%llx-0x%llx]\n", | 1163 | res->name, res, res_list_elem->name, |
1157 | acpi_enforce_resources == ENFORCE_RESOURCES_LAX | 1164 | res_list_elem); |
1158 | ? KERN_WARNING : KERN_ERR, | ||
1159 | ioport ? "I/O" : "Memory", res->name, | ||
1160 | (long long) res->start, (long long) res->end, | ||
1161 | res_list_elem->name, | ||
1162 | (long long) res_list_elem->start, | ||
1163 | (long long) res_list_elem->end); | ||
1164 | if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) | 1165 | if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) |
1165 | printk(KERN_NOTICE "ACPI: This conflict may" | 1166 | printk(KERN_NOTICE "ACPI: This conflict may" |
1166 | " cause random problems and system" | 1167 | " cause random problems and system" |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0261b116d051..0338f513a010 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1081,12 +1081,6 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
1081 | if (ACPI_IS_ROOT_DEVICE(device)) { | 1081 | if (ACPI_IS_ROOT_DEVICE(device)) { |
1082 | acpi_add_id(device, ACPI_SYSTEM_HID); | 1082 | acpi_add_id(device, ACPI_SYSTEM_HID); |
1083 | break; | 1083 | break; |
1084 | } else if (ACPI_IS_ROOT_DEVICE(device->parent)) { | ||
1085 | /* \_SB_, the only root-level namespace device */ | ||
1086 | acpi_add_id(device, ACPI_BUS_HID); | ||
1087 | strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); | ||
1088 | strcpy(device->pnp.device_class, ACPI_BUS_CLASS); | ||
1089 | break; | ||
1090 | } | 1084 | } |
1091 | 1085 | ||
1092 | status = acpi_get_object_info(device->handle, &info); | 1086 | status = acpi_get_object_info(device->handle, &info); |
@@ -1121,6 +1115,12 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
1121 | acpi_add_id(device, ACPI_DOCK_HID); | 1115 | acpi_add_id(device, ACPI_DOCK_HID); |
1122 | else if (!acpi_ibm_smbus_match(device)) | 1116 | else if (!acpi_ibm_smbus_match(device)) |
1123 | acpi_add_id(device, ACPI_SMBUS_IBM_HID); | 1117 | acpi_add_id(device, ACPI_SMBUS_IBM_HID); |
1118 | else if (!acpi_device_hid(device) && | ||
1119 | ACPI_IS_ROOT_DEVICE(device->parent)) { | ||
1120 | acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ | ||
1121 | strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); | ||
1122 | strcpy(device->pnp.device_class, ACPI_BUS_CLASS); | ||
1123 | } | ||
1124 | 1124 | ||
1125 | break; | 1125 | break; |
1126 | case ACPI_BUS_TYPE_POWER: | 1126 | case ACPI_BUS_TYPE_POWER: |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 6a0143796772..a0c93b321482 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/dmi.h> | 44 | #include <linux/dmi.h> |
45 | #include <acpi/acpi_bus.h> | 45 | #include <acpi/acpi_bus.h> |
46 | #include <acpi/acpi_drivers.h> | 46 | #include <acpi/acpi_drivers.h> |
47 | #include <linux/suspend.h> | ||
47 | 48 | ||
48 | #define PREFIX "ACPI: " | 49 | #define PREFIX "ACPI: " |
49 | 50 | ||
@@ -89,7 +90,6 @@ module_param(allow_duplicates, bool, 0644); | |||
89 | static int register_count = 0; | 90 | static int register_count = 0; |
90 | static int acpi_video_bus_add(struct acpi_device *device); | 91 | static int acpi_video_bus_add(struct acpi_device *device); |
91 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 92 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
92 | static int acpi_video_resume(struct acpi_device *device); | ||
93 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); | 93 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); |
94 | 94 | ||
95 | static const struct acpi_device_id video_device_ids[] = { | 95 | static const struct acpi_device_id video_device_ids[] = { |
@@ -105,7 +105,6 @@ static struct acpi_driver acpi_video_bus = { | |||
105 | .ops = { | 105 | .ops = { |
106 | .add = acpi_video_bus_add, | 106 | .add = acpi_video_bus_add, |
107 | .remove = acpi_video_bus_remove, | 107 | .remove = acpi_video_bus_remove, |
108 | .resume = acpi_video_resume, | ||
109 | .notify = acpi_video_bus_notify, | 108 | .notify = acpi_video_bus_notify, |
110 | }, | 109 | }, |
111 | }; | 110 | }; |
@@ -160,6 +159,7 @@ struct acpi_video_bus { | |||
160 | struct proc_dir_entry *dir; | 159 | struct proc_dir_entry *dir; |
161 | struct input_dev *input; | 160 | struct input_dev *input; |
162 | char phys[32]; /* for input device */ | 161 | char phys[32]; /* for input device */ |
162 | struct notifier_block pm_nb; | ||
163 | }; | 163 | }; |
164 | 164 | ||
165 | struct acpi_video_device_flags { | 165 | struct acpi_video_device_flags { |
@@ -1021,6 +1021,13 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
1021 | if (IS_ERR(device->backlight)) | 1021 | if (IS_ERR(device->backlight)) |
1022 | return; | 1022 | return; |
1023 | 1023 | ||
1024 | /* | ||
1025 | * Save current brightness level in case we have to restore it | ||
1026 | * before acpi_video_device_lcd_set_level() is called next time. | ||
1027 | */ | ||
1028 | device->backlight->props.brightness = | ||
1029 | acpi_video_get_brightness(device->backlight); | ||
1030 | |||
1024 | result = sysfs_create_link(&device->backlight->dev.kobj, | 1031 | result = sysfs_create_link(&device->backlight->dev.kobj, |
1025 | &device->dev->dev.kobj, "device"); | 1032 | &device->dev->dev.kobj, "device"); |
1026 | if (result) | 1033 | if (result) |
@@ -2123,7 +2130,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
2123 | { | 2130 | { |
2124 | struct acpi_video_bus *video = acpi_driver_data(device); | 2131 | struct acpi_video_bus *video = acpi_driver_data(device); |
2125 | struct input_dev *input; | 2132 | struct input_dev *input; |
2126 | int keycode; | 2133 | int keycode = 0; |
2127 | 2134 | ||
2128 | if (!video) | 2135 | if (!video) |
2129 | return; | 2136 | return; |
@@ -2159,17 +2166,19 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
2159 | break; | 2166 | break; |
2160 | 2167 | ||
2161 | default: | 2168 | default: |
2162 | keycode = KEY_UNKNOWN; | ||
2163 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 2169 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
2164 | "Unsupported event [0x%x]\n", event)); | 2170 | "Unsupported event [0x%x]\n", event)); |
2165 | break; | 2171 | break; |
2166 | } | 2172 | } |
2167 | 2173 | ||
2168 | acpi_notifier_call_chain(device, event, 0); | 2174 | acpi_notifier_call_chain(device, event, 0); |
2169 | input_report_key(input, keycode, 1); | 2175 | |
2170 | input_sync(input); | 2176 | if (keycode) { |
2171 | input_report_key(input, keycode, 0); | 2177 | input_report_key(input, keycode, 1); |
2172 | input_sync(input); | 2178 | input_sync(input); |
2179 | input_report_key(input, keycode, 0); | ||
2180 | input_sync(input); | ||
2181 | } | ||
2173 | 2182 | ||
2174 | return; | 2183 | return; |
2175 | } | 2184 | } |
@@ -2180,7 +2189,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
2180 | struct acpi_device *device = NULL; | 2189 | struct acpi_device *device = NULL; |
2181 | struct acpi_video_bus *bus; | 2190 | struct acpi_video_bus *bus; |
2182 | struct input_dev *input; | 2191 | struct input_dev *input; |
2183 | int keycode; | 2192 | int keycode = 0; |
2184 | 2193 | ||
2185 | if (!video_device) | 2194 | if (!video_device) |
2186 | return; | 2195 | return; |
@@ -2221,39 +2230,48 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
2221 | keycode = KEY_DISPLAY_OFF; | 2230 | keycode = KEY_DISPLAY_OFF; |
2222 | break; | 2231 | break; |
2223 | default: | 2232 | default: |
2224 | keycode = KEY_UNKNOWN; | ||
2225 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 2233 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
2226 | "Unsupported event [0x%x]\n", event)); | 2234 | "Unsupported event [0x%x]\n", event)); |
2227 | break; | 2235 | break; |
2228 | } | 2236 | } |
2229 | 2237 | ||
2230 | acpi_notifier_call_chain(device, event, 0); | 2238 | acpi_notifier_call_chain(device, event, 0); |
2231 | input_report_key(input, keycode, 1); | 2239 | |
2232 | input_sync(input); | 2240 | if (keycode) { |
2233 | input_report_key(input, keycode, 0); | 2241 | input_report_key(input, keycode, 1); |
2234 | input_sync(input); | 2242 | input_sync(input); |
2243 | input_report_key(input, keycode, 0); | ||
2244 | input_sync(input); | ||
2245 | } | ||
2235 | 2246 | ||
2236 | return; | 2247 | return; |
2237 | } | 2248 | } |
2238 | 2249 | ||
2239 | static int instance; | 2250 | static int acpi_video_resume(struct notifier_block *nb, |
2240 | static int acpi_video_resume(struct acpi_device *device) | 2251 | unsigned long val, void *ign) |
2241 | { | 2252 | { |
2242 | struct acpi_video_bus *video; | 2253 | struct acpi_video_bus *video; |
2243 | struct acpi_video_device *video_device; | 2254 | struct acpi_video_device *video_device; |
2244 | int i; | 2255 | int i; |
2245 | 2256 | ||
2246 | if (!device || !acpi_driver_data(device)) | 2257 | switch (val) { |
2247 | return -EINVAL; | 2258 | case PM_HIBERNATION_PREPARE: |
2259 | case PM_SUSPEND_PREPARE: | ||
2260 | case PM_RESTORE_PREPARE: | ||
2261 | return NOTIFY_DONE; | ||
2262 | } | ||
2248 | 2263 | ||
2249 | video = acpi_driver_data(device); | 2264 | video = container_of(nb, struct acpi_video_bus, pm_nb); |
2265 | |||
2266 | dev_info(&video->device->dev, "Restoring backlight state\n"); | ||
2250 | 2267 | ||
2251 | for (i = 0; i < video->attached_count; i++) { | 2268 | for (i = 0; i < video->attached_count; i++) { |
2252 | video_device = video->attached_array[i].bind_info; | 2269 | video_device = video->attached_array[i].bind_info; |
2253 | if (video_device && video_device->backlight) | 2270 | if (video_device && video_device->backlight) |
2254 | acpi_video_set_brightness(video_device->backlight); | 2271 | acpi_video_set_brightness(video_device->backlight); |
2255 | } | 2272 | } |
2256 | return AE_OK; | 2273 | |
2274 | return NOTIFY_OK; | ||
2257 | } | 2275 | } |
2258 | 2276 | ||
2259 | static acpi_status | 2277 | static acpi_status |
@@ -2277,6 +2295,8 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, | |||
2277 | return AE_OK; | 2295 | return AE_OK; |
2278 | } | 2296 | } |
2279 | 2297 | ||
2298 | static int instance; | ||
2299 | |||
2280 | static int acpi_video_bus_add(struct acpi_device *device) | 2300 | static int acpi_video_bus_add(struct acpi_device *device) |
2281 | { | 2301 | { |
2282 | struct acpi_video_bus *video; | 2302 | struct acpi_video_bus *video; |
@@ -2358,7 +2378,6 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2358 | set_bit(KEY_BRIGHTNESSDOWN, input->keybit); | 2378 | set_bit(KEY_BRIGHTNESSDOWN, input->keybit); |
2359 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | 2379 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); |
2360 | set_bit(KEY_DISPLAY_OFF, input->keybit); | 2380 | set_bit(KEY_DISPLAY_OFF, input->keybit); |
2361 | set_bit(KEY_UNKNOWN, input->keybit); | ||
2362 | 2381 | ||
2363 | error = input_register_device(input); | 2382 | error = input_register_device(input); |
2364 | if (error) | 2383 | if (error) |
@@ -2370,6 +2389,10 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
2370 | video->flags.rom ? "yes" : "no", | 2389 | video->flags.rom ? "yes" : "no", |
2371 | video->flags.post ? "yes" : "no"); | 2390 | video->flags.post ? "yes" : "no"); |
2372 | 2391 | ||
2392 | video->pm_nb.notifier_call = acpi_video_resume; | ||
2393 | video->pm_nb.priority = 0; | ||
2394 | register_pm_notifier(&video->pm_nb); | ||
2395 | |||
2373 | return 0; | 2396 | return 0; |
2374 | 2397 | ||
2375 | err_free_input_dev: | 2398 | err_free_input_dev: |
@@ -2396,6 +2419,8 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
2396 | 2419 | ||
2397 | video = acpi_driver_data(device); | 2420 | video = acpi_driver_data(device); |
2398 | 2421 | ||
2422 | unregister_pm_notifier(&video->pm_nb); | ||
2423 | |||
2399 | acpi_video_bus_stop_devices(video); | 2424 | acpi_video_bus_stop_devices(video); |
2400 | acpi_video_bus_put_devices(video); | 2425 | acpi_video_bus_put_devices(video); |
2401 | acpi_video_bus_remove_fs(device); | 2426 | acpi_video_bus_remove_fs(device); |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 4f4aa5897b4c..933442f40321 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -313,7 +313,7 @@ static ssize_t | |||
313 | print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr, | 313 | print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr, |
314 | char *buf) | 314 | char *buf) |
315 | { | 315 | { |
316 | return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); | 316 | return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE); |
317 | } | 317 | } |
318 | 318 | ||
319 | static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); | 319 | static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL); |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 459f1bc25a7b..c5f22bb0a48e 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) | |||
2533 | Controller->RequestQueue[n] = RequestQueue; | 2533 | Controller->RequestQueue[n] = RequestQueue; |
2534 | blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit); | 2534 | blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit); |
2535 | RequestQueue->queuedata = Controller; | 2535 | RequestQueue->queuedata = Controller; |
2536 | blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit); | ||
2537 | blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); | 2536 | blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); |
2538 | blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); | 2537 | blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); |
2539 | disk->queue = RequestQueue; | 2538 | disk->queue = RequestQueue; |
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 17956ff6a08d..df018990c422 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error) | |||
536 | put_ldev(mdev); | 536 | put_ldev(mdev); |
537 | } | 537 | } |
538 | 538 | ||
539 | /* sector to word */ | ||
539 | #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) | 540 | #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) |
541 | |||
540 | /* activity log to on disk bitmap -- prepare bio unless that sector | 542 | /* activity log to on disk bitmap -- prepare bio unless that sector |
541 | * is already covered by previously prepared bios */ | 543 | * is already covered by previously prepared bios */ |
542 | static int atodb_prepare_unless_covered(struct drbd_conf *mdev, | 544 | static int atodb_prepare_unless_covered(struct drbd_conf *mdev, |
@@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, | |||
546 | { | 548 | { |
547 | struct bio *bio; | 549 | struct bio *bio; |
548 | struct page *page; | 550 | struct page *page; |
549 | sector_t on_disk_sector = enr + mdev->ldev->md.md_offset | 551 | sector_t on_disk_sector; |
550 | + mdev->ldev->md.bm_offset; | ||
551 | unsigned int page_offset = PAGE_SIZE; | 552 | unsigned int page_offset = PAGE_SIZE; |
552 | int offset; | 553 | int offset; |
553 | int i = 0; | 554 | int i = 0; |
554 | int err = -ENOMEM; | 555 | int err = -ENOMEM; |
555 | 556 | ||
557 | /* We always write aligned, full 4k blocks, | ||
558 | * so we can ignore the logical_block_size (for now) */ | ||
559 | enr &= ~7U; | ||
560 | on_disk_sector = enr + mdev->ldev->md.md_offset | ||
561 | + mdev->ldev->md.bm_offset; | ||
562 | |||
563 | D_ASSERT(!(on_disk_sector & 7U)); | ||
564 | |||
556 | /* Check if that enr is already covered by an already created bio. | 565 | /* Check if that enr is already covered by an already created bio. |
557 | * Caution, bios[] is not NULL terminated, | 566 | * Caution, bios[] is not NULL terminated, |
558 | * but only initialized to all NULL. | 567 | * but only initialized to all NULL. |
@@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, | |||
588 | 597 | ||
589 | offset = S2W(enr); | 598 | offset = S2W(enr); |
590 | drbd_bm_get_lel(mdev, offset, | 599 | drbd_bm_get_lel(mdev, offset, |
591 | min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset), | 600 | min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset), |
592 | kmap(page) + page_offset); | 601 | kmap(page) + page_offset); |
593 | kunmap(page); | 602 | kunmap(page); |
594 | 603 | ||
@@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, | |||
597 | bio->bi_bdev = mdev->ldev->md_bdev; | 606 | bio->bi_bdev = mdev->ldev->md_bdev; |
598 | bio->bi_sector = on_disk_sector; | 607 | bio->bi_sector = on_disk_sector; |
599 | 608 | ||
600 | if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE) | 609 | if (bio_add_page(bio, page, 4096, page_offset) != 4096) |
601 | goto out_put_page; | 610 | goto out_put_page; |
602 | 611 | ||
603 | atomic_inc(&wc->count); | 612 | atomic_inc(&wc->count); |
@@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev) | |||
1327 | /* ok, ->resync is there. */ | 1336 | /* ok, ->resync is there. */ |
1328 | for (i = 0; i < mdev->resync->nr_elements; i++) { | 1337 | for (i = 0; i < mdev->resync->nr_elements; i++) { |
1329 | e = lc_element_by_index(mdev->resync, i); | 1338 | e = lc_element_by_index(mdev->resync, i); |
1330 | bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL; | 1339 | bm_ext = lc_entry(e, struct bm_extent, lce); |
1331 | if (bm_ext->lce.lc_number == LC_FREE) | 1340 | if (bm_ext->lce.lc_number == LC_FREE) |
1332 | continue; | 1341 | continue; |
1333 | if (bm_ext->lce.lc_number == mdev->resync_wenr) { | 1342 | if (bm_ext->lce.lc_number == mdev->resync_wenr) { |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index 3d6f3d988949..3390716898d5 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
@@ -67,7 +67,7 @@ struct drbd_bitmap { | |||
67 | size_t bm_words; | 67 | size_t bm_words; |
68 | size_t bm_number_of_pages; | 68 | size_t bm_number_of_pages; |
69 | sector_t bm_dev_capacity; | 69 | sector_t bm_dev_capacity; |
70 | struct semaphore bm_change; /* serializes resize operations */ | 70 | struct mutex bm_change; /* serializes resize operations */ |
71 | 71 | ||
72 | atomic_t bm_async_io; | 72 | atomic_t bm_async_io; |
73 | wait_queue_head_t bm_io_wait; | 73 | wait_queue_head_t bm_io_wait; |
@@ -115,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) | |||
115 | return; | 115 | return; |
116 | } | 116 | } |
117 | 117 | ||
118 | trylock_failed = down_trylock(&b->bm_change); | 118 | trylock_failed = !mutex_trylock(&b->bm_change); |
119 | 119 | ||
120 | if (trylock_failed) { | 120 | if (trylock_failed) { |
121 | dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n", | 121 | dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n", |
@@ -126,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) | |||
126 | b->bm_task == mdev->receiver.task ? "receiver" : | 126 | b->bm_task == mdev->receiver.task ? "receiver" : |
127 | b->bm_task == mdev->asender.task ? "asender" : | 127 | b->bm_task == mdev->asender.task ? "asender" : |
128 | b->bm_task == mdev->worker.task ? "worker" : "?"); | 128 | b->bm_task == mdev->worker.task ? "worker" : "?"); |
129 | down(&b->bm_change); | 129 | mutex_lock(&b->bm_change); |
130 | } | 130 | } |
131 | if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) | 131 | if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) |
132 | dev_err(DEV, "FIXME bitmap already locked in bm_lock\n"); | 132 | dev_err(DEV, "FIXME bitmap already locked in bm_lock\n"); |
@@ -148,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev) | |||
148 | 148 | ||
149 | b->bm_why = NULL; | 149 | b->bm_why = NULL; |
150 | b->bm_task = NULL; | 150 | b->bm_task = NULL; |
151 | up(&b->bm_change); | 151 | mutex_unlock(&b->bm_change); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* word offset to long pointer */ | 154 | /* word offset to long pointer */ |
@@ -296,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev) | |||
296 | if (!b) | 296 | if (!b) |
297 | return -ENOMEM; | 297 | return -ENOMEM; |
298 | spin_lock_init(&b->bm_lock); | 298 | spin_lock_init(&b->bm_lock); |
299 | init_MUTEX(&b->bm_change); | 299 | mutex_init(&b->bm_change); |
300 | init_waitqueue_head(&b->bm_io_wait); | 300 | init_waitqueue_head(&b->bm_io_wait); |
301 | 301 | ||
302 | mdev->bitmap = b; | 302 | mdev->bitmap = b; |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index d9301e861d9f..e5e86a781820 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd) | |||
261 | [P_OV_REQUEST] = "OVRequest", | 261 | [P_OV_REQUEST] = "OVRequest", |
262 | [P_OV_REPLY] = "OVReply", | 262 | [P_OV_REPLY] = "OVReply", |
263 | [P_OV_RESULT] = "OVResult", | 263 | [P_OV_RESULT] = "OVResult", |
264 | [P_CSUM_RS_REQUEST] = "CsumRSRequest", | ||
265 | [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", | ||
266 | [P_COMPRESSED_BITMAP] = "CBitmap", | ||
264 | [P_MAX_CMD] = NULL, | 267 | [P_MAX_CMD] = NULL, |
265 | }; | 268 | }; |
266 | 269 | ||
@@ -443,13 +446,18 @@ struct p_rs_param_89 { | |||
443 | char csums_alg[SHARED_SECRET_MAX]; | 446 | char csums_alg[SHARED_SECRET_MAX]; |
444 | } __packed; | 447 | } __packed; |
445 | 448 | ||
449 | enum drbd_conn_flags { | ||
450 | CF_WANT_LOSE = 1, | ||
451 | CF_DRY_RUN = 2, | ||
452 | }; | ||
453 | |||
446 | struct p_protocol { | 454 | struct p_protocol { |
447 | struct p_header head; | 455 | struct p_header head; |
448 | u32 protocol; | 456 | u32 protocol; |
449 | u32 after_sb_0p; | 457 | u32 after_sb_0p; |
450 | u32 after_sb_1p; | 458 | u32 after_sb_1p; |
451 | u32 after_sb_2p; | 459 | u32 after_sb_2p; |
452 | u32 want_lose; | 460 | u32 conn_flags; |
453 | u32 two_primaries; | 461 | u32 two_primaries; |
454 | 462 | ||
455 | /* Since protocol version 87 and higher. */ | 463 | /* Since protocol version 87 and higher. */ |
@@ -791,6 +799,8 @@ enum { | |||
791 | * while this is set. */ | 799 | * while this is set. */ |
792 | RESIZE_PENDING, /* Size change detected locally, waiting for the response from | 800 | RESIZE_PENDING, /* Size change detected locally, waiting for the response from |
793 | * the peer, if it changed there as well. */ | 801 | * the peer, if it changed there as well. */ |
802 | CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ | ||
803 | GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ | ||
794 | }; | 804 | }; |
795 | 805 | ||
796 | struct drbd_bitmap; /* opaque for drbd_conf */ | 806 | struct drbd_bitmap; /* opaque for drbd_conf */ |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ab871e00ffc5..67e0fc542249 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc) | |||
1668 | int drbd_send_protocol(struct drbd_conf *mdev) | 1668 | int drbd_send_protocol(struct drbd_conf *mdev) |
1669 | { | 1669 | { |
1670 | struct p_protocol *p; | 1670 | struct p_protocol *p; |
1671 | int size, rv; | 1671 | int size, cf, rv; |
1672 | 1672 | ||
1673 | size = sizeof(struct p_protocol); | 1673 | size = sizeof(struct p_protocol); |
1674 | 1674 | ||
@@ -1685,9 +1685,21 @@ int drbd_send_protocol(struct drbd_conf *mdev) | |||
1685 | p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); | 1685 | p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); |
1686 | p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); | 1686 | p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); |
1687 | p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); | 1687 | p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); |
1688 | p->want_lose = cpu_to_be32(mdev->net_conf->want_lose); | ||
1689 | p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); | 1688 | p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); |
1690 | 1689 | ||
1690 | cf = 0; | ||
1691 | if (mdev->net_conf->want_lose) | ||
1692 | cf |= CF_WANT_LOSE; | ||
1693 | if (mdev->net_conf->dry_run) { | ||
1694 | if (mdev->agreed_pro_version >= 92) | ||
1695 | cf |= CF_DRY_RUN; | ||
1696 | else { | ||
1697 | dev_err(DEV, "--dry-run is not supported by peer"); | ||
1698 | return 0; | ||
1699 | } | ||
1700 | } | ||
1701 | p->conn_flags = cpu_to_be32(cf); | ||
1702 | |||
1691 | if (mdev->agreed_pro_version >= 87) | 1703 | if (mdev->agreed_pro_version >= 87) |
1692 | strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); | 1704 | strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); |
1693 | 1705 | ||
@@ -3161,14 +3173,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) | |||
3161 | void drbd_free_sock(struct drbd_conf *mdev) | 3173 | void drbd_free_sock(struct drbd_conf *mdev) |
3162 | { | 3174 | { |
3163 | if (mdev->data.socket) { | 3175 | if (mdev->data.socket) { |
3176 | mutex_lock(&mdev->data.mutex); | ||
3164 | kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); | 3177 | kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); |
3165 | sock_release(mdev->data.socket); | 3178 | sock_release(mdev->data.socket); |
3166 | mdev->data.socket = NULL; | 3179 | mdev->data.socket = NULL; |
3180 | mutex_unlock(&mdev->data.mutex); | ||
3167 | } | 3181 | } |
3168 | if (mdev->meta.socket) { | 3182 | if (mdev->meta.socket) { |
3183 | mutex_lock(&mdev->meta.mutex); | ||
3169 | kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); | 3184 | kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); |
3170 | sock_release(mdev->meta.socket); | 3185 | sock_release(mdev->meta.socket); |
3171 | mdev->meta.socket = NULL; | 3186 | mdev->meta.socket = NULL; |
3187 | mutex_unlock(&mdev->meta.mutex); | ||
3172 | } | 3188 | } |
3173 | } | 3189 | } |
3174 | 3190 | ||
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 4df3b40b1057..6429d2b19e06 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | if (r == SS_NO_UP_TO_DATE_DISK && force && | 287 | if (r == SS_NO_UP_TO_DATE_DISK && force && |
288 | (mdev->state.disk == D_INCONSISTENT || | 288 | (mdev->state.disk < D_UP_TO_DATE && |
289 | mdev->state.disk == D_OUTDATED)) { | 289 | mdev->state.disk >= D_INCONSISTENT)) { |
290 | mask.disk = D_MASK; | 290 | mask.disk = D_MASK; |
291 | val.disk = D_UP_TO_DATE; | 291 | val.disk = D_UP_TO_DATE; |
292 | forced = 1; | 292 | forced = 1; |
@@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, | |||
407 | } | 407 | } |
408 | 408 | ||
409 | reply->ret_code = | 409 | reply->ret_code = |
410 | drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer); | 410 | drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force); |
411 | 411 | ||
412 | return 0; | 412 | return 0; |
413 | } | 413 | } |
@@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
941 | 941 | ||
942 | drbd_md_set_sector_offsets(mdev, nbc); | 942 | drbd_md_set_sector_offsets(mdev, nbc); |
943 | 943 | ||
944 | /* allocate a second IO page if logical_block_size != 512 */ | ||
945 | logical_block_size = bdev_logical_block_size(nbc->md_bdev); | ||
946 | if (logical_block_size == 0) | ||
947 | logical_block_size = MD_SECTOR_SIZE; | ||
948 | |||
949 | if (logical_block_size != MD_SECTOR_SIZE) { | ||
950 | if (!mdev->md_io_tmpp) { | ||
951 | struct page *page = alloc_page(GFP_NOIO); | ||
952 | if (!page) | ||
953 | goto force_diskless_dec; | ||
954 | |||
955 | dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", | ||
956 | logical_block_size, MD_SECTOR_SIZE); | ||
957 | dev_warn(DEV, "Workaround engaged (has performance impact).\n"); | ||
958 | |||
959 | mdev->md_io_tmpp = page; | ||
960 | } | ||
961 | } | ||
962 | |||
944 | if (!mdev->bitmap) { | 963 | if (!mdev->bitmap) { |
945 | if (drbd_bm_init(mdev)) { | 964 | if (drbd_bm_init(mdev)) { |
946 | retcode = ERR_NOMEM; | 965 | retcode = ERR_NOMEM; |
@@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp | |||
980 | goto force_diskless_dec; | 999 | goto force_diskless_dec; |
981 | } | 1000 | } |
982 | 1001 | ||
983 | /* allocate a second IO page if logical_block_size != 512 */ | ||
984 | logical_block_size = bdev_logical_block_size(nbc->md_bdev); | ||
985 | if (logical_block_size == 0) | ||
986 | logical_block_size = MD_SECTOR_SIZE; | ||
987 | |||
988 | if (logical_block_size != MD_SECTOR_SIZE) { | ||
989 | if (!mdev->md_io_tmpp) { | ||
990 | struct page *page = alloc_page(GFP_NOIO); | ||
991 | if (!page) | ||
992 | goto force_diskless_dec; | ||
993 | |||
994 | dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", | ||
995 | logical_block_size, MD_SECTOR_SIZE); | ||
996 | dev_warn(DEV, "Workaround engaged (has performance impact).\n"); | ||
997 | |||
998 | mdev->md_io_tmpp = page; | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | /* Reset the "barriers don't work" bits here, then force meta data to | 1002 | /* Reset the "barriers don't work" bits here, then force meta data to |
1003 | * be written, to ensure we determine if barriers are supported. */ | 1003 | * be written, to ensure we determine if barriers are supported. */ |
1004 | if (nbc->dc.no_md_flush) | 1004 | if (nbc->dc.no_md_flush) |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d065c646b35a..ed9f1de24a71 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -2513,6 +2513,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol | |||
2513 | } | 2513 | } |
2514 | 2514 | ||
2515 | if (hg == -100) { | 2515 | if (hg == -100) { |
2516 | /* FIXME this log message is not correct if we end up here | ||
2517 | * after an attempted attach on a diskless node. | ||
2518 | * We just refuse to attach -- well, we drop the "connection" | ||
2519 | * to that disk, in a way... */ | ||
2516 | dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); | 2520 | dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); |
2517 | drbd_khelper(mdev, "split-brain"); | 2521 | drbd_khelper(mdev, "split-brain"); |
2518 | return C_MASK; | 2522 | return C_MASK; |
@@ -2538,6 +2542,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol | |||
2538 | } | 2542 | } |
2539 | } | 2543 | } |
2540 | 2544 | ||
2545 | if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) { | ||
2546 | if (hg == 0) | ||
2547 | dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n"); | ||
2548 | else | ||
2549 | dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.", | ||
2550 | drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET), | ||
2551 | abs(hg) >= 2 ? "full" : "bit-map based"); | ||
2552 | return C_MASK; | ||
2553 | } | ||
2554 | |||
2541 | if (abs(hg) >= 2) { | 2555 | if (abs(hg) >= 2) { |
2542 | dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); | 2556 | dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); |
2543 | if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) | 2557 | if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) |
@@ -2585,7 +2599,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) | |||
2585 | struct p_protocol *p = (struct p_protocol *)h; | 2599 | struct p_protocol *p = (struct p_protocol *)h; |
2586 | int header_size, data_size; | 2600 | int header_size, data_size; |
2587 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; | 2601 | int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; |
2588 | int p_want_lose, p_two_primaries; | 2602 | int p_want_lose, p_two_primaries, cf; |
2589 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; | 2603 | char p_integrity_alg[SHARED_SECRET_MAX] = ""; |
2590 | 2604 | ||
2591 | header_size = sizeof(*p) - sizeof(*h); | 2605 | header_size = sizeof(*p) - sizeof(*h); |
@@ -2598,8 +2612,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) | |||
2598 | p_after_sb_0p = be32_to_cpu(p->after_sb_0p); | 2612 | p_after_sb_0p = be32_to_cpu(p->after_sb_0p); |
2599 | p_after_sb_1p = be32_to_cpu(p->after_sb_1p); | 2613 | p_after_sb_1p = be32_to_cpu(p->after_sb_1p); |
2600 | p_after_sb_2p = be32_to_cpu(p->after_sb_2p); | 2614 | p_after_sb_2p = be32_to_cpu(p->after_sb_2p); |
2601 | p_want_lose = be32_to_cpu(p->want_lose); | ||
2602 | p_two_primaries = be32_to_cpu(p->two_primaries); | 2615 | p_two_primaries = be32_to_cpu(p->two_primaries); |
2616 | cf = be32_to_cpu(p->conn_flags); | ||
2617 | p_want_lose = cf & CF_WANT_LOSE; | ||
2618 | |||
2619 | clear_bit(CONN_DRY_RUN, &mdev->flags); | ||
2620 | |||
2621 | if (cf & CF_DRY_RUN) | ||
2622 | set_bit(CONN_DRY_RUN, &mdev->flags); | ||
2603 | 2623 | ||
2604 | if (p_proto != mdev->net_conf->wire_protocol) { | 2624 | if (p_proto != mdev->net_conf->wire_protocol) { |
2605 | dev_err(DEV, "incompatible communication protocols\n"); | 2625 | dev_err(DEV, "incompatible communication protocols\n"); |
@@ -3118,13 +3138,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h) | |||
3118 | 3138 | ||
3119 | put_ldev(mdev); | 3139 | put_ldev(mdev); |
3120 | if (nconn == C_MASK) { | 3140 | if (nconn == C_MASK) { |
3141 | nconn = C_CONNECTED; | ||
3121 | if (mdev->state.disk == D_NEGOTIATING) { | 3142 | if (mdev->state.disk == D_NEGOTIATING) { |
3122 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); | 3143 | drbd_force_state(mdev, NS(disk, D_DISKLESS)); |
3123 | nconn = C_CONNECTED; | ||
3124 | } else if (peer_state.disk == D_NEGOTIATING) { | 3144 | } else if (peer_state.disk == D_NEGOTIATING) { |
3125 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); | 3145 | dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); |
3126 | peer_state.disk = D_DISKLESS; | 3146 | peer_state.disk = D_DISKLESS; |
3147 | real_peer_disk = D_DISKLESS; | ||
3127 | } else { | 3148 | } else { |
3149 | if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) | ||
3150 | return FALSE; | ||
3128 | D_ASSERT(oconn == C_WF_REPORT_PARAMS); | 3151 | D_ASSERT(oconn == C_WF_REPORT_PARAMS); |
3129 | drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); | 3152 | drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); |
3130 | return FALSE; | 3153 | return FALSE; |
@@ -3594,10 +3617,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) | |||
3594 | 3617 | ||
3595 | /* asender does not clean up anything. it must not interfere, either */ | 3618 | /* asender does not clean up anything. it must not interfere, either */ |
3596 | drbd_thread_stop(&mdev->asender); | 3619 | drbd_thread_stop(&mdev->asender); |
3597 | |||
3598 | mutex_lock(&mdev->data.mutex); | ||
3599 | drbd_free_sock(mdev); | 3620 | drbd_free_sock(mdev); |
3600 | mutex_unlock(&mdev->data.mutex); | ||
3601 | 3621 | ||
3602 | spin_lock_irq(&mdev->req_lock); | 3622 | spin_lock_irq(&mdev->req_lock); |
3603 | _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); | 3623 | _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); |
@@ -4054,6 +4074,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h) | |||
4054 | { | 4074 | { |
4055 | /* restore idle timeout */ | 4075 | /* restore idle timeout */ |
4056 | mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; | 4076 | mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; |
4077 | if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags)) | ||
4078 | wake_up(&mdev->misc_wait); | ||
4057 | 4079 | ||
4058 | return TRUE; | 4080 | return TRUE; |
4059 | } | 4081 | } |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b453c2bca3be..44bf6d11197e 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | |||
938 | 938 | ||
939 | if (eq) { | 939 | if (eq) { |
940 | drbd_set_in_sync(mdev, e->sector, e->size); | 940 | drbd_set_in_sync(mdev, e->sector, e->size); |
941 | mdev->rs_same_csum++; | 941 | /* rs_same_csums unit is BM_BLOCK_SIZE */ |
942 | mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT; | ||
942 | ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e); | 943 | ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e); |
943 | } else { | 944 | } else { |
944 | inc_rs_pending(mdev); | 945 | inc_rs_pending(mdev); |
@@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na) | |||
1288 | return retcode; | 1289 | return retcode; |
1289 | } | 1290 | } |
1290 | 1291 | ||
1292 | static void ping_peer(struct drbd_conf *mdev) | ||
1293 | { | ||
1294 | clear_bit(GOT_PING_ACK, &mdev->flags); | ||
1295 | request_ping(mdev); | ||
1296 | wait_event(mdev->misc_wait, | ||
1297 | test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED); | ||
1298 | } | ||
1299 | |||
1291 | /** | 1300 | /** |
1292 | * drbd_start_resync() - Start the resync process | 1301 | * drbd_start_resync() - Start the resync process |
1293 | * @mdev: DRBD device. | 1302 | * @mdev: DRBD device. |
@@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) | |||
1371 | _drbd_pause_after(mdev); | 1380 | _drbd_pause_after(mdev); |
1372 | } | 1381 | } |
1373 | write_unlock_irq(&global_state_lock); | 1382 | write_unlock_irq(&global_state_lock); |
1374 | drbd_state_unlock(mdev); | ||
1375 | put_ldev(mdev); | 1383 | put_ldev(mdev); |
1376 | 1384 | ||
1377 | if (r == SS_SUCCESS) { | 1385 | if (r == SS_SUCCESS) { |
@@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) | |||
1382 | 1390 | ||
1383 | if (mdev->rs_total == 0) { | 1391 | if (mdev->rs_total == 0) { |
1384 | /* Peer still reachable? Beware of failing before-resync-target handlers! */ | 1392 | /* Peer still reachable? Beware of failing before-resync-target handlers! */ |
1385 | request_ping(mdev); | 1393 | ping_peer(mdev); |
1386 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1387 | schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */ | ||
1388 | drbd_resync_finished(mdev); | 1394 | drbd_resync_finished(mdev); |
1389 | return; | ||
1390 | } | 1395 | } |
1391 | 1396 | ||
1392 | /* ns.conn may already be != mdev->state.conn, | 1397 | /* ns.conn may already be != mdev->state.conn, |
@@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) | |||
1398 | 1403 | ||
1399 | drbd_md_sync(mdev); | 1404 | drbd_md_sync(mdev); |
1400 | } | 1405 | } |
1406 | drbd_state_unlock(mdev); | ||
1401 | } | 1407 | } |
1402 | 1408 | ||
1403 | int drbd_worker(struct drbd_thread *thi) | 1409 | int drbd_worker(struct drbd_thread *thi) |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index cb69929d917a..8546d123b9a7 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -237,6 +237,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | |||
237 | if (ret) | 237 | if (ret) |
238 | goto fail; | 238 | goto fail; |
239 | 239 | ||
240 | file_update_time(file); | ||
241 | |||
240 | transfer_result = lo_do_transfer(lo, WRITE, page, offset, | 242 | transfer_result = lo_do_transfer(lo, WRITE, page, offset, |
241 | bvec->bv_page, bv_offs, size, IV); | 243 | bvec->bv_page, bv_offs, size, IV); |
242 | copied = size; | 244 | copied = size; |
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 8866ca369d5e..71acf4e53356 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg) | |||
341 | && (j++ < PCD_SPIN)) | 341 | && (j++ < PCD_SPIN)) |
342 | udelay(PCD_DELAY); | 342 | udelay(PCD_DELAY); |
343 | 343 | ||
344 | if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) { | 344 | if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) { |
345 | s = read_reg(cd, 7); | 345 | s = read_reg(cd, 7); |
346 | e = read_reg(cd, 1); | 346 | e = read_reg(cd, 1); |
347 | p = read_reg(cd, 2); | 347 | p = read_reg(cd, 2); |
348 | if (j >= PCD_SPIN) | 348 | if (j > PCD_SPIN) |
349 | e |= 0x100; | 349 | e |= 0x100; |
350 | if (fun) | 350 | if (fun) |
351 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" | 351 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" |
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index ddb4f9abd480..c059aab3006b 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c | |||
@@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg) | |||
391 | && (j++ < PF_SPIN)) | 391 | && (j++ < PF_SPIN)) |
392 | udelay(PF_SPIN_DEL); | 392 | udelay(PF_SPIN_DEL); |
393 | 393 | ||
394 | if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) { | 394 | if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) { |
395 | s = read_reg(pf, 7); | 395 | s = read_reg(pf, 7); |
396 | e = read_reg(pf, 1); | 396 | e = read_reg(pf, 1); |
397 | p = read_reg(pf, 2); | 397 | p = read_reg(pf, 2); |
398 | if (j >= PF_SPIN) | 398 | if (j > PF_SPIN) |
399 | e |= 0x100; | 399 | e |= 0x100; |
400 | if (fun) | 400 | if (fun) |
401 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" | 401 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 1e4006e18f03..bc5825fdeaab 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg) | |||
274 | && (j++ < PT_SPIN)) | 274 | && (j++ < PT_SPIN)) |
275 | udelay(PT_SPIN_DEL); | 275 | udelay(PT_SPIN_DEL); |
276 | 276 | ||
277 | if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) { | 277 | if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) { |
278 | s = read_reg(pi, 7); | 278 | s = read_reg(pi, 7); |
279 | e = read_reg(pi, 1); | 279 | e = read_reg(pi, 1); |
280 | p = read_reg(pi, 2); | 280 | p = read_reg(pi, 2); |
281 | if (j >= PT_SPIN) | 281 | if (j > PT_SPIN) |
282 | e |= 0x100; | 282 | e |= 0x100; |
283 | if (fun) | 283 | if (fun) |
284 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" | 284 | printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 4b12b820c9a6..2138a7ae050c 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -348,14 +348,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
348 | set_capacity(vblk->disk, cap); | 348 | set_capacity(vblk->disk, cap); |
349 | 349 | ||
350 | /* We can handle whatever the host told us to handle. */ | 350 | /* We can handle whatever the host told us to handle. */ |
351 | blk_queue_max_phys_segments(q, vblk->sg_elems-2); | 351 | blk_queue_max_segments(q, vblk->sg_elems-2); |
352 | blk_queue_max_hw_segments(q, vblk->sg_elems-2); | ||
353 | 352 | ||
354 | /* No need to bounce any requests */ | 353 | /* No need to bounce any requests */ |
355 | blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); | 354 | blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); |
356 | 355 | ||
357 | /* No real sector limit. */ | 356 | /* No real sector limit. */ |
358 | blk_queue_max_sectors(q, -1U); | 357 | blk_queue_max_hw_sectors(q, -1U); |
359 | 358 | ||
360 | /* Host can optionally specify maximum segment size and number of | 359 | /* Host can optionally specify maximum segment size and number of |
361 | * segments. */ | 360 | * segments. */ |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index d41331bc2aa7..aa4248efc5d8 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -1817,8 +1817,6 @@ static int intel_845_configure(void) | |||
1817 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); | 1817 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); |
1818 | /* clear any possible error conditions */ | 1818 | /* clear any possible error conditions */ |
1819 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); | 1819 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); |
1820 | |||
1821 | intel_i830_setup_flush(); | ||
1822 | return 0; | 1820 | return 0; |
1823 | } | 1821 | } |
1824 | 1822 | ||
@@ -2188,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
2188 | .agp_destroy_page = agp_generic_destroy_page, | 2186 | .agp_destroy_page = agp_generic_destroy_page, |
2189 | .agp_destroy_pages = agp_generic_destroy_pages, | 2187 | .agp_destroy_pages = agp_generic_destroy_pages, |
2190 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 2188 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
2191 | .chipset_flush = intel_i830_chipset_flush, | ||
2192 | }; | 2189 | }; |
2193 | 2190 | ||
2194 | static const struct agp_bridge_driver intel_850_driver = { | 2191 | static const struct agp_bridge_driver intel_850_driver = { |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c9bc896d68af..90b199f97bec 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, | |||
1026 | 1026 | ||
1027 | xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ | 1027 | xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ |
1028 | /* last check before exit */ | 1028 | /* last check before exit */ |
1029 | if (!io_detect_cm4000(iobase, dev)) | 1029 | if (!io_detect_cm4000(iobase, dev)) { |
1030 | count = -ENODEV; | 1030 | rc = -ENODEV; |
1031 | goto release_io; | ||
1032 | } | ||
1031 | 1033 | ||
1032 | if (test_bit(IS_INVREV, &dev->flags) && count > 0) | 1034 | if (test_bit(IS_INVREV, &dev->flags) && count > 0) |
1033 | str_invert_revert(dev->rbuf, count); | 1035 | str_invert_revert(dev->rbuf, count); |
1034 | 1036 | ||
1035 | if (copy_to_user(buf, dev->rbuf, count)) | 1037 | if (copy_to_user(buf, dev->rbuf, count)) |
1036 | return -EFAULT; | 1038 | rc = -EFAULT; |
1037 | 1039 | ||
1038 | release_io: | 1040 | release_io: |
1039 | clear_bit(LOCK_IO, &dev->flags); | 1041 | clear_bit(LOCK_IO, &dev->flags); |
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 702dcc98c074..14a34d99eea2 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c | |||
@@ -960,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) | |||
960 | u.packet.header_length = GET_HEADER_LENGTH(control); | 960 | u.packet.header_length = GET_HEADER_LENGTH(control); |
961 | 961 | ||
962 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { | 962 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { |
963 | if (u.packet.header_length % 4 != 0) | ||
964 | return -EINVAL; | ||
963 | header_length = u.packet.header_length; | 965 | header_length = u.packet.header_length; |
964 | } else { | 966 | } else { |
965 | /* | 967 | /* |
@@ -969,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg) | |||
969 | if (ctx->header_size == 0) { | 971 | if (ctx->header_size == 0) { |
970 | if (u.packet.header_length > 0) | 972 | if (u.packet.header_length > 0) |
971 | return -EINVAL; | 973 | return -EINVAL; |
972 | } else if (u.packet.header_length % ctx->header_size != 0) { | 974 | } else if (u.packet.header_length == 0 || |
975 | u.packet.header_length % ctx->header_size != 0) { | ||
973 | return -EINVAL; | 976 | return -EINVAL; |
974 | } | 977 | } |
975 | header_length = 0; | 978 | header_length = 0; |
@@ -1354,24 +1357,24 @@ static int dispatch_ioctl(struct client *client, | |||
1354 | return -ENODEV; | 1357 | return -ENODEV; |
1355 | 1358 | ||
1356 | if (_IOC_TYPE(cmd) != '#' || | 1359 | if (_IOC_TYPE(cmd) != '#' || |
1357 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) | 1360 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || |
1361 | _IOC_SIZE(cmd) > sizeof(buffer)) | ||
1358 | return -EINVAL; | 1362 | return -EINVAL; |
1359 | 1363 | ||
1360 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 1364 | if (_IOC_DIR(cmd) == _IOC_READ) |
1361 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1365 | memset(&buffer, 0, _IOC_SIZE(cmd)); |
1362 | copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) | 1366 | |
1367 | if (_IOC_DIR(cmd) & _IOC_WRITE) | ||
1368 | if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) | ||
1363 | return -EFAULT; | 1369 | return -EFAULT; |
1364 | } | ||
1365 | 1370 | ||
1366 | ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer); | 1371 | ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer); |
1367 | if (ret < 0) | 1372 | if (ret < 0) |
1368 | return ret; | 1373 | return ret; |
1369 | 1374 | ||
1370 | if (_IOC_DIR(cmd) & _IOC_READ) { | 1375 | if (_IOC_DIR(cmd) & _IOC_READ) |
1371 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1376 | if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) |
1372 | copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) | ||
1373 | return -EFAULT; | 1377 | return -EFAULT; |
1374 | } | ||
1375 | 1378 | ||
1376 | return ret; | 1379 | return ret; |
1377 | } | 1380 | } |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 2cc6e87d849d..18f41d7061f0 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -85,6 +85,8 @@ static struct edid_quirk { | |||
85 | 85 | ||
86 | /* Envision Peripherals, Inc. EN-7100e */ | 86 | /* Envision Peripherals, Inc. EN-7100e */ |
87 | { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, | 87 | { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, |
88 | /* Envision EN2028 */ | ||
89 | { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 }, | ||
88 | 90 | ||
89 | /* Funai Electronics PM36B */ | 91 | /* Funai Electronics PM36B */ |
90 | { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | | 92 | { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index b743411d8144..a0c365f2e521 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -516,8 +516,6 @@ void drm_put_dev(struct drm_device *dev) | |||
516 | } | 516 | } |
517 | driver = dev->driver; | 517 | driver = dev->driver; |
518 | 518 | ||
519 | drm_vblank_cleanup(dev); | ||
520 | |||
521 | drm_lastclose(dev); | 519 | drm_lastclose(dev); |
522 | 520 | ||
523 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && | 521 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && |
@@ -537,6 +535,8 @@ void drm_put_dev(struct drm_device *dev) | |||
537 | dev->agp = NULL; | 535 | dev->agp = NULL; |
538 | } | 536 | } |
539 | 537 | ||
538 | drm_vblank_cleanup(dev); | ||
539 | |||
540 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) | 540 | list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) |
541 | drm_rmmap(dev, r_list->map); | 541 | drm_rmmap(dev, r_list->map); |
542 | drm_ht_remove(&dev->map_hash); | 542 | drm_ht_remove(&dev->map_hash); |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b574503dddd0..a0b8447b06e7 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -226,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) | |||
226 | } else { | 226 | } else { |
227 | struct drm_i915_gem_object *obj_priv; | 227 | struct drm_i915_gem_object *obj_priv; |
228 | 228 | ||
229 | obj_priv = obj->driver_private; | 229 | obj_priv = to_intel_bo(obj); |
230 | seq_printf(m, "Fenced object[%2d] = %p: %s " | 230 | seq_printf(m, "Fenced object[%2d] = %p: %s " |
231 | "%08x %08zx %08x %s %08x %08x %d", | 231 | "%08x %08zx %08x %s %08x %08x %d", |
232 | i, obj, get_pin_flag(obj_priv), | 232 | i, obj, get_pin_flag(obj_priv), |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4b26919abdb2..0af3dcc85ce9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -80,14 +80,14 @@ const static struct intel_device_info intel_i915g_info = { | |||
80 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 80 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
81 | }; | 81 | }; |
82 | const static struct intel_device_info intel_i915gm_info = { | 82 | const static struct intel_device_info intel_i915gm_info = { |
83 | .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, | 83 | .is_i9xx = 1, .is_mobile = 1, |
84 | .cursor_needs_physical = 1, | 84 | .cursor_needs_physical = 1, |
85 | }; | 85 | }; |
86 | const static struct intel_device_info intel_i945g_info = { | 86 | const static struct intel_device_info intel_i945g_info = { |
87 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 87 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
88 | }; | 88 | }; |
89 | const static struct intel_device_info intel_i945gm_info = { | 89 | const static struct intel_device_info intel_i945gm_info = { |
90 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, | 90 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
91 | .has_hotplug = 1, .cursor_needs_physical = 1, | 91 | .has_hotplug = 1, .cursor_needs_physical = 1, |
92 | }; | 92 | }; |
93 | 93 | ||
@@ -361,7 +361,7 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
361 | !dev_priv->mm.suspended) { | 361 | !dev_priv->mm.suspended) { |
362 | drm_i915_ring_buffer_t *ring = &dev_priv->ring; | 362 | drm_i915_ring_buffer_t *ring = &dev_priv->ring; |
363 | struct drm_gem_object *obj = ring->ring_obj; | 363 | struct drm_gem_object *obj = ring->ring_obj; |
364 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 364 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
365 | dev_priv->mm.suspended = 0; | 365 | dev_priv->mm.suspended = 0; |
366 | 366 | ||
367 | /* Stop the ring if it's running. */ | 367 | /* Stop the ring if it's running. */ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aba8260fbc5e..6960849522f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -611,6 +611,8 @@ typedef struct drm_i915_private { | |||
611 | /* Reclocking support */ | 611 | /* Reclocking support */ |
612 | bool render_reclock_avail; | 612 | bool render_reclock_avail; |
613 | bool lvds_downclock_avail; | 613 | bool lvds_downclock_avail; |
614 | /* indicate whether the LVDS EDID is OK */ | ||
615 | bool lvds_edid_good; | ||
614 | /* indicates the reduced downclock for LVDS*/ | 616 | /* indicates the reduced downclock for LVDS*/ |
615 | int lvds_downclock; | 617 | int lvds_downclock; |
616 | struct work_struct idle_work; | 618 | struct work_struct idle_work; |
@@ -731,6 +733,8 @@ struct drm_i915_gem_object { | |||
731 | atomic_t pending_flip; | 733 | atomic_t pending_flip; |
732 | }; | 734 | }; |
733 | 735 | ||
736 | #define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private) | ||
737 | |||
734 | /** | 738 | /** |
735 | * Request queue structure. | 739 | * Request queue structure. |
736 | * | 740 | * |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 368d726853d1..80871c62a571 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -163,7 +163,7 @@ fast_shmem_read(struct page **pages, | |||
163 | static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) | 163 | static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) |
164 | { | 164 | { |
165 | drm_i915_private_t *dev_priv = obj->dev->dev_private; | 165 | drm_i915_private_t *dev_priv = obj->dev->dev_private; |
166 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 166 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
167 | 167 | ||
168 | return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && | 168 | return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && |
169 | obj_priv->tiling_mode != I915_TILING_NONE; | 169 | obj_priv->tiling_mode != I915_TILING_NONE; |
@@ -264,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
264 | struct drm_i915_gem_pread *args, | 264 | struct drm_i915_gem_pread *args, |
265 | struct drm_file *file_priv) | 265 | struct drm_file *file_priv) |
266 | { | 266 | { |
267 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 267 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
268 | ssize_t remain; | 268 | ssize_t remain; |
269 | loff_t offset, page_base; | 269 | loff_t offset, page_base; |
270 | char __user *user_data; | 270 | char __user *user_data; |
@@ -285,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
285 | if (ret != 0) | 285 | if (ret != 0) |
286 | goto fail_put_pages; | 286 | goto fail_put_pages; |
287 | 287 | ||
288 | obj_priv = obj->driver_private; | 288 | obj_priv = to_intel_bo(obj); |
289 | offset = args->offset; | 289 | offset = args->offset; |
290 | 290 | ||
291 | while (remain > 0) { | 291 | while (remain > 0) { |
@@ -354,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
354 | struct drm_i915_gem_pread *args, | 354 | struct drm_i915_gem_pread *args, |
355 | struct drm_file *file_priv) | 355 | struct drm_file *file_priv) |
356 | { | 356 | { |
357 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 357 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
358 | struct mm_struct *mm = current->mm; | 358 | struct mm_struct *mm = current->mm; |
359 | struct page **user_pages; | 359 | struct page **user_pages; |
360 | ssize_t remain; | 360 | ssize_t remain; |
@@ -403,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
403 | if (ret != 0) | 403 | if (ret != 0) |
404 | goto fail_put_pages; | 404 | goto fail_put_pages; |
405 | 405 | ||
406 | obj_priv = obj->driver_private; | 406 | obj_priv = to_intel_bo(obj); |
407 | offset = args->offset; | 407 | offset = args->offset; |
408 | 408 | ||
409 | while (remain > 0) { | 409 | while (remain > 0) { |
@@ -479,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
479 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 479 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
480 | if (obj == NULL) | 480 | if (obj == NULL) |
481 | return -EBADF; | 481 | return -EBADF; |
482 | obj_priv = obj->driver_private; | 482 | obj_priv = to_intel_bo(obj); |
483 | 483 | ||
484 | /* Bounds check source. | 484 | /* Bounds check source. |
485 | * | 485 | * |
@@ -581,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
581 | struct drm_i915_gem_pwrite *args, | 581 | struct drm_i915_gem_pwrite *args, |
582 | struct drm_file *file_priv) | 582 | struct drm_file *file_priv) |
583 | { | 583 | { |
584 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 584 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
585 | drm_i915_private_t *dev_priv = dev->dev_private; | 585 | drm_i915_private_t *dev_priv = dev->dev_private; |
586 | ssize_t remain; | 586 | ssize_t remain; |
587 | loff_t offset, page_base; | 587 | loff_t offset, page_base; |
@@ -605,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
605 | if (ret) | 605 | if (ret) |
606 | goto fail; | 606 | goto fail; |
607 | 607 | ||
608 | obj_priv = obj->driver_private; | 608 | obj_priv = to_intel_bo(obj); |
609 | offset = obj_priv->gtt_offset + args->offset; | 609 | offset = obj_priv->gtt_offset + args->offset; |
610 | 610 | ||
611 | while (remain > 0) { | 611 | while (remain > 0) { |
@@ -655,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
655 | struct drm_i915_gem_pwrite *args, | 655 | struct drm_i915_gem_pwrite *args, |
656 | struct drm_file *file_priv) | 656 | struct drm_file *file_priv) |
657 | { | 657 | { |
658 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 658 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
659 | drm_i915_private_t *dev_priv = dev->dev_private; | 659 | drm_i915_private_t *dev_priv = dev->dev_private; |
660 | ssize_t remain; | 660 | ssize_t remain; |
661 | loff_t gtt_page_base, offset; | 661 | loff_t gtt_page_base, offset; |
@@ -699,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
699 | if (ret) | 699 | if (ret) |
700 | goto out_unpin_object; | 700 | goto out_unpin_object; |
701 | 701 | ||
702 | obj_priv = obj->driver_private; | 702 | obj_priv = to_intel_bo(obj); |
703 | offset = obj_priv->gtt_offset + args->offset; | 703 | offset = obj_priv->gtt_offset + args->offset; |
704 | 704 | ||
705 | while (remain > 0) { | 705 | while (remain > 0) { |
@@ -761,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
761 | struct drm_i915_gem_pwrite *args, | 761 | struct drm_i915_gem_pwrite *args, |
762 | struct drm_file *file_priv) | 762 | struct drm_file *file_priv) |
763 | { | 763 | { |
764 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 764 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
765 | ssize_t remain; | 765 | ssize_t remain; |
766 | loff_t offset, page_base; | 766 | loff_t offset, page_base; |
767 | char __user *user_data; | 767 | char __user *user_data; |
@@ -781,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
781 | if (ret != 0) | 781 | if (ret != 0) |
782 | goto fail_put_pages; | 782 | goto fail_put_pages; |
783 | 783 | ||
784 | obj_priv = obj->driver_private; | 784 | obj_priv = to_intel_bo(obj); |
785 | offset = args->offset; | 785 | offset = args->offset; |
786 | obj_priv->dirty = 1; | 786 | obj_priv->dirty = 1; |
787 | 787 | ||
@@ -829,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
829 | struct drm_i915_gem_pwrite *args, | 829 | struct drm_i915_gem_pwrite *args, |
830 | struct drm_file *file_priv) | 830 | struct drm_file *file_priv) |
831 | { | 831 | { |
832 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 832 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
833 | struct mm_struct *mm = current->mm; | 833 | struct mm_struct *mm = current->mm; |
834 | struct page **user_pages; | 834 | struct page **user_pages; |
835 | ssize_t remain; | 835 | ssize_t remain; |
@@ -877,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
877 | if (ret != 0) | 877 | if (ret != 0) |
878 | goto fail_put_pages; | 878 | goto fail_put_pages; |
879 | 879 | ||
880 | obj_priv = obj->driver_private; | 880 | obj_priv = to_intel_bo(obj); |
881 | offset = args->offset; | 881 | offset = args->offset; |
882 | obj_priv->dirty = 1; | 882 | obj_priv->dirty = 1; |
883 | 883 | ||
@@ -952,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
952 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 952 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
953 | if (obj == NULL) | 953 | if (obj == NULL) |
954 | return -EBADF; | 954 | return -EBADF; |
955 | obj_priv = obj->driver_private; | 955 | obj_priv = to_intel_bo(obj); |
956 | 956 | ||
957 | /* Bounds check destination. | 957 | /* Bounds check destination. |
958 | * | 958 | * |
@@ -1034,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1034 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 1034 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
1035 | if (obj == NULL) | 1035 | if (obj == NULL) |
1036 | return -EBADF; | 1036 | return -EBADF; |
1037 | obj_priv = obj->driver_private; | 1037 | obj_priv = to_intel_bo(obj); |
1038 | 1038 | ||
1039 | mutex_lock(&dev->struct_mutex); | 1039 | mutex_lock(&dev->struct_mutex); |
1040 | 1040 | ||
@@ -1096,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1096 | DRM_INFO("%s: sw_finish %d (%p %zd)\n", | 1096 | DRM_INFO("%s: sw_finish %d (%p %zd)\n", |
1097 | __func__, args->handle, obj, obj->size); | 1097 | __func__, args->handle, obj, obj->size); |
1098 | #endif | 1098 | #endif |
1099 | obj_priv = obj->driver_private; | 1099 | obj_priv = to_intel_bo(obj); |
1100 | 1100 | ||
1101 | /* Pinned buffers may be scanout, so flush the cache */ | 1101 | /* Pinned buffers may be scanout, so flush the cache */ |
1102 | if (obj_priv->pin_count) | 1102 | if (obj_priv->pin_count) |
@@ -1167,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1167 | struct drm_gem_object *obj = vma->vm_private_data; | 1167 | struct drm_gem_object *obj = vma->vm_private_data; |
1168 | struct drm_device *dev = obj->dev; | 1168 | struct drm_device *dev = obj->dev; |
1169 | struct drm_i915_private *dev_priv = dev->dev_private; | 1169 | struct drm_i915_private *dev_priv = dev->dev_private; |
1170 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1170 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1171 | pgoff_t page_offset; | 1171 | pgoff_t page_offset; |
1172 | unsigned long pfn; | 1172 | unsigned long pfn; |
1173 | int ret = 0; | 1173 | int ret = 0; |
@@ -1234,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
1234 | { | 1234 | { |
1235 | struct drm_device *dev = obj->dev; | 1235 | struct drm_device *dev = obj->dev; |
1236 | struct drm_gem_mm *mm = dev->mm_private; | 1236 | struct drm_gem_mm *mm = dev->mm_private; |
1237 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1237 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1238 | struct drm_map_list *list; | 1238 | struct drm_map_list *list; |
1239 | struct drm_local_map *map; | 1239 | struct drm_local_map *map; |
1240 | int ret = 0; | 1240 | int ret = 0; |
@@ -1305,7 +1305,7 @@ void | |||
1305 | i915_gem_release_mmap(struct drm_gem_object *obj) | 1305 | i915_gem_release_mmap(struct drm_gem_object *obj) |
1306 | { | 1306 | { |
1307 | struct drm_device *dev = obj->dev; | 1307 | struct drm_device *dev = obj->dev; |
1308 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1308 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1309 | 1309 | ||
1310 | if (dev->dev_mapping) | 1310 | if (dev->dev_mapping) |
1311 | unmap_mapping_range(dev->dev_mapping, | 1311 | unmap_mapping_range(dev->dev_mapping, |
@@ -1316,7 +1316,7 @@ static void | |||
1316 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1316 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) |
1317 | { | 1317 | { |
1318 | struct drm_device *dev = obj->dev; | 1318 | struct drm_device *dev = obj->dev; |
1319 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1319 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1320 | struct drm_gem_mm *mm = dev->mm_private; | 1320 | struct drm_gem_mm *mm = dev->mm_private; |
1321 | struct drm_map_list *list; | 1321 | struct drm_map_list *list; |
1322 | 1322 | ||
@@ -1347,7 +1347,7 @@ static uint32_t | |||
1347 | i915_gem_get_gtt_alignment(struct drm_gem_object *obj) | 1347 | i915_gem_get_gtt_alignment(struct drm_gem_object *obj) |
1348 | { | 1348 | { |
1349 | struct drm_device *dev = obj->dev; | 1349 | struct drm_device *dev = obj->dev; |
1350 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1350 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1351 | int start, i; | 1351 | int start, i; |
1352 | 1352 | ||
1353 | /* | 1353 | /* |
@@ -1406,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1406 | 1406 | ||
1407 | mutex_lock(&dev->struct_mutex); | 1407 | mutex_lock(&dev->struct_mutex); |
1408 | 1408 | ||
1409 | obj_priv = obj->driver_private; | 1409 | obj_priv = to_intel_bo(obj); |
1410 | 1410 | ||
1411 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 1411 | if (obj_priv->madv != I915_MADV_WILLNEED) { |
1412 | DRM_ERROR("Attempting to mmap a purgeable buffer\n"); | 1412 | DRM_ERROR("Attempting to mmap a purgeable buffer\n"); |
@@ -1450,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1450 | void | 1450 | void |
1451 | i915_gem_object_put_pages(struct drm_gem_object *obj) | 1451 | i915_gem_object_put_pages(struct drm_gem_object *obj) |
1452 | { | 1452 | { |
1453 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1453 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1454 | int page_count = obj->size / PAGE_SIZE; | 1454 | int page_count = obj->size / PAGE_SIZE; |
1455 | int i; | 1455 | int i; |
1456 | 1456 | ||
@@ -1486,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) | |||
1486 | { | 1486 | { |
1487 | struct drm_device *dev = obj->dev; | 1487 | struct drm_device *dev = obj->dev; |
1488 | drm_i915_private_t *dev_priv = dev->dev_private; | 1488 | drm_i915_private_t *dev_priv = dev->dev_private; |
1489 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1489 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1490 | 1490 | ||
1491 | /* Add a reference if we're newly entering the active list. */ | 1491 | /* Add a reference if we're newly entering the active list. */ |
1492 | if (!obj_priv->active) { | 1492 | if (!obj_priv->active) { |
@@ -1506,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) | |||
1506 | { | 1506 | { |
1507 | struct drm_device *dev = obj->dev; | 1507 | struct drm_device *dev = obj->dev; |
1508 | drm_i915_private_t *dev_priv = dev->dev_private; | 1508 | drm_i915_private_t *dev_priv = dev->dev_private; |
1509 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1509 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1510 | 1510 | ||
1511 | BUG_ON(!obj_priv->active); | 1511 | BUG_ON(!obj_priv->active); |
1512 | list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); | 1512 | list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); |
@@ -1517,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) | |||
1517 | static void | 1517 | static void |
1518 | i915_gem_object_truncate(struct drm_gem_object *obj) | 1518 | i915_gem_object_truncate(struct drm_gem_object *obj) |
1519 | { | 1519 | { |
1520 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1520 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1521 | struct inode *inode; | 1521 | struct inode *inode; |
1522 | 1522 | ||
1523 | inode = obj->filp->f_path.dentry->d_inode; | 1523 | inode = obj->filp->f_path.dentry->d_inode; |
@@ -1538,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
1538 | { | 1538 | { |
1539 | struct drm_device *dev = obj->dev; | 1539 | struct drm_device *dev = obj->dev; |
1540 | drm_i915_private_t *dev_priv = dev->dev_private; | 1540 | drm_i915_private_t *dev_priv = dev->dev_private; |
1541 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1541 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1542 | 1542 | ||
1543 | i915_verify_inactive(dev, __FILE__, __LINE__); | 1543 | i915_verify_inactive(dev, __FILE__, __LINE__); |
1544 | if (obj_priv->pin_count != 0) | 1544 | if (obj_priv->pin_count != 0) |
@@ -1965,7 +1965,7 @@ static int | |||
1965 | i915_gem_object_wait_rendering(struct drm_gem_object *obj) | 1965 | i915_gem_object_wait_rendering(struct drm_gem_object *obj) |
1966 | { | 1966 | { |
1967 | struct drm_device *dev = obj->dev; | 1967 | struct drm_device *dev = obj->dev; |
1968 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1968 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1969 | int ret; | 1969 | int ret; |
1970 | 1970 | ||
1971 | /* This function only exists to support waiting for existing rendering, | 1971 | /* This function only exists to support waiting for existing rendering, |
@@ -1997,7 +1997,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1997 | { | 1997 | { |
1998 | struct drm_device *dev = obj->dev; | 1998 | struct drm_device *dev = obj->dev; |
1999 | drm_i915_private_t *dev_priv = dev->dev_private; | 1999 | drm_i915_private_t *dev_priv = dev->dev_private; |
2000 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2000 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2001 | int ret = 0; | 2001 | int ret = 0; |
2002 | 2002 | ||
2003 | #if WATCH_BUF | 2003 | #if WATCH_BUF |
@@ -2173,7 +2173,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2173 | #if WATCH_LRU | 2173 | #if WATCH_LRU |
2174 | DRM_INFO("%s: evicting %p\n", __func__, obj); | 2174 | DRM_INFO("%s: evicting %p\n", __func__, obj); |
2175 | #endif | 2175 | #endif |
2176 | obj_priv = obj->driver_private; | 2176 | obj_priv = to_intel_bo(obj); |
2177 | BUG_ON(obj_priv->pin_count != 0); | 2177 | BUG_ON(obj_priv->pin_count != 0); |
2178 | BUG_ON(obj_priv->active); | 2178 | BUG_ON(obj_priv->active); |
2179 | 2179 | ||
@@ -2244,7 +2244,7 @@ int | |||
2244 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 2244 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
2245 | gfp_t gfpmask) | 2245 | gfp_t gfpmask) |
2246 | { | 2246 | { |
2247 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2247 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2248 | int page_count, i; | 2248 | int page_count, i; |
2249 | struct address_space *mapping; | 2249 | struct address_space *mapping; |
2250 | struct inode *inode; | 2250 | struct inode *inode; |
@@ -2297,7 +2297,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2297 | struct drm_gem_object *obj = reg->obj; | 2297 | struct drm_gem_object *obj = reg->obj; |
2298 | struct drm_device *dev = obj->dev; | 2298 | struct drm_device *dev = obj->dev; |
2299 | drm_i915_private_t *dev_priv = dev->dev_private; | 2299 | drm_i915_private_t *dev_priv = dev->dev_private; |
2300 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2300 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2301 | int regnum = obj_priv->fence_reg; | 2301 | int regnum = obj_priv->fence_reg; |
2302 | uint64_t val; | 2302 | uint64_t val; |
2303 | 2303 | ||
@@ -2319,7 +2319,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2319 | struct drm_gem_object *obj = reg->obj; | 2319 | struct drm_gem_object *obj = reg->obj; |
2320 | struct drm_device *dev = obj->dev; | 2320 | struct drm_device *dev = obj->dev; |
2321 | drm_i915_private_t *dev_priv = dev->dev_private; | 2321 | drm_i915_private_t *dev_priv = dev->dev_private; |
2322 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2322 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2323 | int regnum = obj_priv->fence_reg; | 2323 | int regnum = obj_priv->fence_reg; |
2324 | uint64_t val; | 2324 | uint64_t val; |
2325 | 2325 | ||
@@ -2339,7 +2339,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2339 | struct drm_gem_object *obj = reg->obj; | 2339 | struct drm_gem_object *obj = reg->obj; |
2340 | struct drm_device *dev = obj->dev; | 2340 | struct drm_device *dev = obj->dev; |
2341 | drm_i915_private_t *dev_priv = dev->dev_private; | 2341 | drm_i915_private_t *dev_priv = dev->dev_private; |
2342 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2342 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2343 | int regnum = obj_priv->fence_reg; | 2343 | int regnum = obj_priv->fence_reg; |
2344 | int tile_width; | 2344 | int tile_width; |
2345 | uint32_t fence_reg, val; | 2345 | uint32_t fence_reg, val; |
@@ -2381,7 +2381,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
2381 | struct drm_gem_object *obj = reg->obj; | 2381 | struct drm_gem_object *obj = reg->obj; |
2382 | struct drm_device *dev = obj->dev; | 2382 | struct drm_device *dev = obj->dev; |
2383 | drm_i915_private_t *dev_priv = dev->dev_private; | 2383 | drm_i915_private_t *dev_priv = dev->dev_private; |
2384 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2384 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2385 | int regnum = obj_priv->fence_reg; | 2385 | int regnum = obj_priv->fence_reg; |
2386 | uint32_t val; | 2386 | uint32_t val; |
2387 | uint32_t pitch_val; | 2387 | uint32_t pitch_val; |
@@ -2425,7 +2425,7 @@ static int i915_find_fence_reg(struct drm_device *dev) | |||
2425 | if (!reg->obj) | 2425 | if (!reg->obj) |
2426 | return i; | 2426 | return i; |
2427 | 2427 | ||
2428 | obj_priv = reg->obj->driver_private; | 2428 | obj_priv = to_intel_bo(reg->obj); |
2429 | if (!obj_priv->pin_count) | 2429 | if (!obj_priv->pin_count) |
2430 | avail++; | 2430 | avail++; |
2431 | } | 2431 | } |
@@ -2480,7 +2480,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2480 | { | 2480 | { |
2481 | struct drm_device *dev = obj->dev; | 2481 | struct drm_device *dev = obj->dev; |
2482 | struct drm_i915_private *dev_priv = dev->dev_private; | 2482 | struct drm_i915_private *dev_priv = dev->dev_private; |
2483 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2483 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2484 | struct drm_i915_fence_reg *reg = NULL; | 2484 | struct drm_i915_fence_reg *reg = NULL; |
2485 | int ret; | 2485 | int ret; |
2486 | 2486 | ||
@@ -2547,7 +2547,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2547 | { | 2547 | { |
2548 | struct drm_device *dev = obj->dev; | 2548 | struct drm_device *dev = obj->dev; |
2549 | drm_i915_private_t *dev_priv = dev->dev_private; | 2549 | drm_i915_private_t *dev_priv = dev->dev_private; |
2550 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2550 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2551 | 2551 | ||
2552 | if (IS_GEN6(dev)) { | 2552 | if (IS_GEN6(dev)) { |
2553 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2553 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
@@ -2583,7 +2583,7 @@ int | |||
2583 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | 2583 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj) |
2584 | { | 2584 | { |
2585 | struct drm_device *dev = obj->dev; | 2585 | struct drm_device *dev = obj->dev; |
2586 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2586 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2587 | 2587 | ||
2588 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE) | 2588 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE) |
2589 | return 0; | 2589 | return 0; |
@@ -2621,7 +2621,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2621 | { | 2621 | { |
2622 | struct drm_device *dev = obj->dev; | 2622 | struct drm_device *dev = obj->dev; |
2623 | drm_i915_private_t *dev_priv = dev->dev_private; | 2623 | drm_i915_private_t *dev_priv = dev->dev_private; |
2624 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2624 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2625 | struct drm_mm_node *free_space; | 2625 | struct drm_mm_node *free_space; |
2626 | gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; | 2626 | gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; |
2627 | int ret; | 2627 | int ret; |
@@ -2728,7 +2728,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2728 | void | 2728 | void |
2729 | i915_gem_clflush_object(struct drm_gem_object *obj) | 2729 | i915_gem_clflush_object(struct drm_gem_object *obj) |
2730 | { | 2730 | { |
2731 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2731 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2732 | 2732 | ||
2733 | /* If we don't have a page list set up, then we're not pinned | 2733 | /* If we don't have a page list set up, then we're not pinned |
2734 | * to GPU, and we can ignore the cache flush because it'll happen | 2734 | * to GPU, and we can ignore the cache flush because it'll happen |
@@ -2829,7 +2829,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj) | |||
2829 | int | 2829 | int |
2830 | i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) | 2830 | i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) |
2831 | { | 2831 | { |
2832 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2832 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2833 | uint32_t old_write_domain, old_read_domains; | 2833 | uint32_t old_write_domain, old_read_domains; |
2834 | int ret; | 2834 | int ret; |
2835 | 2835 | ||
@@ -2879,7 +2879,7 @@ int | |||
2879 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | 2879 | i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) |
2880 | { | 2880 | { |
2881 | struct drm_device *dev = obj->dev; | 2881 | struct drm_device *dev = obj->dev; |
2882 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2882 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2883 | uint32_t old_write_domain, old_read_domains; | 2883 | uint32_t old_write_domain, old_read_domains; |
2884 | int ret; | 2884 | int ret; |
2885 | 2885 | ||
@@ -3092,7 +3092,7 @@ static void | |||
3092 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 3092 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
3093 | { | 3093 | { |
3094 | struct drm_device *dev = obj->dev; | 3094 | struct drm_device *dev = obj->dev; |
3095 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3095 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3096 | uint32_t invalidate_domains = 0; | 3096 | uint32_t invalidate_domains = 0; |
3097 | uint32_t flush_domains = 0; | 3097 | uint32_t flush_domains = 0; |
3098 | uint32_t old_read_domains; | 3098 | uint32_t old_read_domains; |
@@ -3177,7 +3177,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
3177 | static void | 3177 | static void |
3178 | i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) | 3178 | i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) |
3179 | { | 3179 | { |
3180 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3180 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3181 | 3181 | ||
3182 | if (!obj_priv->page_cpu_valid) | 3182 | if (!obj_priv->page_cpu_valid) |
3183 | return; | 3183 | return; |
@@ -3217,7 +3217,7 @@ static int | |||
3217 | i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | 3217 | i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, |
3218 | uint64_t offset, uint64_t size) | 3218 | uint64_t offset, uint64_t size) |
3219 | { | 3219 | { |
3220 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3220 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3221 | uint32_t old_read_domains; | 3221 | uint32_t old_read_domains; |
3222 | int i, ret; | 3222 | int i, ret; |
3223 | 3223 | ||
@@ -3286,7 +3286,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3286 | { | 3286 | { |
3287 | struct drm_device *dev = obj->dev; | 3287 | struct drm_device *dev = obj->dev; |
3288 | drm_i915_private_t *dev_priv = dev->dev_private; | 3288 | drm_i915_private_t *dev_priv = dev->dev_private; |
3289 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3289 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3290 | int i, ret; | 3290 | int i, ret; |
3291 | void __iomem *reloc_page; | 3291 | void __iomem *reloc_page; |
3292 | bool need_fence; | 3292 | bool need_fence; |
@@ -3337,7 +3337,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3337 | i915_gem_object_unpin(obj); | 3337 | i915_gem_object_unpin(obj); |
3338 | return -EBADF; | 3338 | return -EBADF; |
3339 | } | 3339 | } |
3340 | target_obj_priv = target_obj->driver_private; | 3340 | target_obj_priv = to_intel_bo(target_obj); |
3341 | 3341 | ||
3342 | #if WATCH_RELOC | 3342 | #if WATCH_RELOC |
3343 | DRM_INFO("%s: obj %p offset %08x target %d " | 3343 | DRM_INFO("%s: obj %p offset %08x target %d " |
@@ -3689,7 +3689,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, | |||
3689 | prepare_to_wait(&dev_priv->pending_flip_queue, | 3689 | prepare_to_wait(&dev_priv->pending_flip_queue, |
3690 | &wait, TASK_INTERRUPTIBLE); | 3690 | &wait, TASK_INTERRUPTIBLE); |
3691 | for (i = 0; i < count; i++) { | 3691 | for (i = 0; i < count; i++) { |
3692 | obj_priv = object_list[i]->driver_private; | 3692 | obj_priv = to_intel_bo(object_list[i]); |
3693 | if (atomic_read(&obj_priv->pending_flip) > 0) | 3693 | if (atomic_read(&obj_priv->pending_flip) > 0) |
3694 | break; | 3694 | break; |
3695 | } | 3695 | } |
@@ -3798,7 +3798,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3798 | goto err; | 3798 | goto err; |
3799 | } | 3799 | } |
3800 | 3800 | ||
3801 | obj_priv = object_list[i]->driver_private; | 3801 | obj_priv = to_intel_bo(object_list[i]); |
3802 | if (obj_priv->in_execbuffer) { | 3802 | if (obj_priv->in_execbuffer) { |
3803 | DRM_ERROR("Object %p appears more than once in object list\n", | 3803 | DRM_ERROR("Object %p appears more than once in object list\n", |
3804 | object_list[i]); | 3804 | object_list[i]); |
@@ -3924,7 +3924,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3924 | 3924 | ||
3925 | for (i = 0; i < args->buffer_count; i++) { | 3925 | for (i = 0; i < args->buffer_count; i++) { |
3926 | struct drm_gem_object *obj = object_list[i]; | 3926 | struct drm_gem_object *obj = object_list[i]; |
3927 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 3927 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3928 | uint32_t old_write_domain = obj->write_domain; | 3928 | uint32_t old_write_domain = obj->write_domain; |
3929 | 3929 | ||
3930 | obj->write_domain = obj->pending_write_domain; | 3930 | obj->write_domain = obj->pending_write_domain; |
@@ -3999,7 +3999,7 @@ err: | |||
3999 | 3999 | ||
4000 | for (i = 0; i < args->buffer_count; i++) { | 4000 | for (i = 0; i < args->buffer_count; i++) { |
4001 | if (object_list[i]) { | 4001 | if (object_list[i]) { |
4002 | obj_priv = object_list[i]->driver_private; | 4002 | obj_priv = to_intel_bo(object_list[i]); |
4003 | obj_priv->in_execbuffer = false; | 4003 | obj_priv->in_execbuffer = false; |
4004 | } | 4004 | } |
4005 | drm_gem_object_unreference(object_list[i]); | 4005 | drm_gem_object_unreference(object_list[i]); |
@@ -4177,7 +4177,7 @@ int | |||
4177 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | 4177 | i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) |
4178 | { | 4178 | { |
4179 | struct drm_device *dev = obj->dev; | 4179 | struct drm_device *dev = obj->dev; |
4180 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 4180 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4181 | int ret; | 4181 | int ret; |
4182 | 4182 | ||
4183 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4183 | i915_verify_inactive(dev, __FILE__, __LINE__); |
@@ -4210,7 +4210,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) | |||
4210 | { | 4210 | { |
4211 | struct drm_device *dev = obj->dev; | 4211 | struct drm_device *dev = obj->dev; |
4212 | drm_i915_private_t *dev_priv = dev->dev_private; | 4212 | drm_i915_private_t *dev_priv = dev->dev_private; |
4213 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 4213 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4214 | 4214 | ||
4215 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4215 | i915_verify_inactive(dev, __FILE__, __LINE__); |
4216 | obj_priv->pin_count--; | 4216 | obj_priv->pin_count--; |
@@ -4250,7 +4250,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, | |||
4250 | mutex_unlock(&dev->struct_mutex); | 4250 | mutex_unlock(&dev->struct_mutex); |
4251 | return -EBADF; | 4251 | return -EBADF; |
4252 | } | 4252 | } |
4253 | obj_priv = obj->driver_private; | 4253 | obj_priv = to_intel_bo(obj); |
4254 | 4254 | ||
4255 | if (obj_priv->madv != I915_MADV_WILLNEED) { | 4255 | if (obj_priv->madv != I915_MADV_WILLNEED) { |
4256 | DRM_ERROR("Attempting to pin a purgeable buffer\n"); | 4256 | DRM_ERROR("Attempting to pin a purgeable buffer\n"); |
@@ -4307,7 +4307,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, | |||
4307 | return -EBADF; | 4307 | return -EBADF; |
4308 | } | 4308 | } |
4309 | 4309 | ||
4310 | obj_priv = obj->driver_private; | 4310 | obj_priv = to_intel_bo(obj); |
4311 | if (obj_priv->pin_filp != file_priv) { | 4311 | if (obj_priv->pin_filp != file_priv) { |
4312 | DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", | 4312 | DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", |
4313 | args->handle); | 4313 | args->handle); |
@@ -4349,7 +4349,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4349 | */ | 4349 | */ |
4350 | i915_gem_retire_requests(dev); | 4350 | i915_gem_retire_requests(dev); |
4351 | 4351 | ||
4352 | obj_priv = obj->driver_private; | 4352 | obj_priv = to_intel_bo(obj); |
4353 | /* Don't count being on the flushing list against the object being | 4353 | /* Don't count being on the flushing list against the object being |
4354 | * done. Otherwise, a buffer left on the flushing list but not getting | 4354 | * done. Otherwise, a buffer left on the flushing list but not getting |
4355 | * flushed (because nobody's flushing that domain) won't ever return | 4355 | * flushed (because nobody's flushing that domain) won't ever return |
@@ -4395,7 +4395,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | |||
4395 | } | 4395 | } |
4396 | 4396 | ||
4397 | mutex_lock(&dev->struct_mutex); | 4397 | mutex_lock(&dev->struct_mutex); |
4398 | obj_priv = obj->driver_private; | 4398 | obj_priv = to_intel_bo(obj); |
4399 | 4399 | ||
4400 | if (obj_priv->pin_count) { | 4400 | if (obj_priv->pin_count) { |
4401 | drm_gem_object_unreference(obj); | 4401 | drm_gem_object_unreference(obj); |
@@ -4456,7 +4456,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
4456 | void i915_gem_free_object(struct drm_gem_object *obj) | 4456 | void i915_gem_free_object(struct drm_gem_object *obj) |
4457 | { | 4457 | { |
4458 | struct drm_device *dev = obj->dev; | 4458 | struct drm_device *dev = obj->dev; |
4459 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 4459 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4460 | 4460 | ||
4461 | trace_i915_gem_object_destroy(obj); | 4461 | trace_i915_gem_object_destroy(obj); |
4462 | 4462 | ||
@@ -4565,7 +4565,7 @@ i915_gem_init_hws(struct drm_device *dev) | |||
4565 | DRM_ERROR("Failed to allocate status page\n"); | 4565 | DRM_ERROR("Failed to allocate status page\n"); |
4566 | return -ENOMEM; | 4566 | return -ENOMEM; |
4567 | } | 4567 | } |
4568 | obj_priv = obj->driver_private; | 4568 | obj_priv = to_intel_bo(obj); |
4569 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | 4569 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; |
4570 | 4570 | ||
4571 | ret = i915_gem_object_pin(obj, 4096); | 4571 | ret = i915_gem_object_pin(obj, 4096); |
@@ -4609,7 +4609,7 @@ i915_gem_cleanup_hws(struct drm_device *dev) | |||
4609 | return; | 4609 | return; |
4610 | 4610 | ||
4611 | obj = dev_priv->hws_obj; | 4611 | obj = dev_priv->hws_obj; |
4612 | obj_priv = obj->driver_private; | 4612 | obj_priv = to_intel_bo(obj); |
4613 | 4613 | ||
4614 | kunmap(obj_priv->pages[0]); | 4614 | kunmap(obj_priv->pages[0]); |
4615 | i915_gem_object_unpin(obj); | 4615 | i915_gem_object_unpin(obj); |
@@ -4643,7 +4643,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4643 | i915_gem_cleanup_hws(dev); | 4643 | i915_gem_cleanup_hws(dev); |
4644 | return -ENOMEM; | 4644 | return -ENOMEM; |
4645 | } | 4645 | } |
4646 | obj_priv = obj->driver_private; | 4646 | obj_priv = to_intel_bo(obj); |
4647 | 4647 | ||
4648 | ret = i915_gem_object_pin(obj, 4096); | 4648 | ret = i915_gem_object_pin(obj, 4096); |
4649 | if (ret != 0) { | 4649 | if (ret != 0) { |
@@ -4936,7 +4936,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
4936 | int ret; | 4936 | int ret; |
4937 | int page_count; | 4937 | int page_count; |
4938 | 4938 | ||
4939 | obj_priv = obj->driver_private; | 4939 | obj_priv = to_intel_bo(obj); |
4940 | if (!obj_priv->phys_obj) | 4940 | if (!obj_priv->phys_obj) |
4941 | return; | 4941 | return; |
4942 | 4942 | ||
@@ -4975,7 +4975,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4975 | if (id > I915_MAX_PHYS_OBJECT) | 4975 | if (id > I915_MAX_PHYS_OBJECT) |
4976 | return -EINVAL; | 4976 | return -EINVAL; |
4977 | 4977 | ||
4978 | obj_priv = obj->driver_private; | 4978 | obj_priv = to_intel_bo(obj); |
4979 | 4979 | ||
4980 | if (obj_priv->phys_obj) { | 4980 | if (obj_priv->phys_obj) { |
4981 | if (obj_priv->phys_obj->id == id) | 4981 | if (obj_priv->phys_obj->id == id) |
@@ -5026,7 +5026,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
5026 | struct drm_i915_gem_pwrite *args, | 5026 | struct drm_i915_gem_pwrite *args, |
5027 | struct drm_file *file_priv) | 5027 | struct drm_file *file_priv) |
5028 | { | 5028 | { |
5029 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 5029 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
5030 | void *obj_addr; | 5030 | void *obj_addr; |
5031 | int ret; | 5031 | int ret; |
5032 | char __user *user_data; | 5032 | char __user *user_data; |
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index e602614bd3f8..35507cf53fa3 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -72,7 +72,7 @@ void | |||
72 | i915_gem_dump_object(struct drm_gem_object *obj, int len, | 72 | i915_gem_dump_object(struct drm_gem_object *obj, int len, |
73 | const char *where, uint32_t mark) | 73 | const char *where, uint32_t mark) |
74 | { | 74 | { |
75 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 75 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
76 | int page; | 76 | int page; |
77 | 77 | ||
78 | DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); | 78 | DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); |
@@ -137,7 +137,7 @@ void | |||
137 | i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | 137 | i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) |
138 | { | 138 | { |
139 | struct drm_device *dev = obj->dev; | 139 | struct drm_device *dev = obj->dev; |
140 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 140 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
141 | int page; | 141 | int page; |
142 | uint32_t *gtt_mapping; | 142 | uint32_t *gtt_mapping; |
143 | uint32_t *backing_map = NULL; | 143 | uint32_t *backing_map = NULL; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index c01c878e51ba..449157f71610 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -240,7 +240,7 @@ bool | |||
240 | i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) | 240 | i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) |
241 | { | 241 | { |
242 | struct drm_device *dev = obj->dev; | 242 | struct drm_device *dev = obj->dev; |
243 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 243 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
244 | 244 | ||
245 | if (obj_priv->gtt_space == NULL) | 245 | if (obj_priv->gtt_space == NULL) |
246 | return true; | 246 | return true; |
@@ -280,7 +280,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
280 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 280 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
281 | if (obj == NULL) | 281 | if (obj == NULL) |
282 | return -EINVAL; | 282 | return -EINVAL; |
283 | obj_priv = obj->driver_private; | 283 | obj_priv = to_intel_bo(obj); |
284 | 284 | ||
285 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { | 285 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { |
286 | drm_gem_object_unreference_unlocked(obj); | 286 | drm_gem_object_unreference_unlocked(obj); |
@@ -364,7 +364,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
364 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 364 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
365 | if (obj == NULL) | 365 | if (obj == NULL) |
366 | return -EINVAL; | 366 | return -EINVAL; |
367 | obj_priv = obj->driver_private; | 367 | obj_priv = to_intel_bo(obj); |
368 | 368 | ||
369 | mutex_lock(&dev->struct_mutex); | 369 | mutex_lock(&dev->struct_mutex); |
370 | 370 | ||
@@ -427,7 +427,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) | |||
427 | { | 427 | { |
428 | struct drm_device *dev = obj->dev; | 428 | struct drm_device *dev = obj->dev; |
429 | drm_i915_private_t *dev_priv = dev->dev_private; | 429 | drm_i915_private_t *dev_priv = dev->dev_private; |
430 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 430 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
431 | int page_count = obj->size >> PAGE_SHIFT; | 431 | int page_count = obj->size >> PAGE_SHIFT; |
432 | int i; | 432 | int i; |
433 | 433 | ||
@@ -456,7 +456,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) | |||
456 | { | 456 | { |
457 | struct drm_device *dev = obj->dev; | 457 | struct drm_device *dev = obj->dev; |
458 | drm_i915_private_t *dev_priv = dev->dev_private; | 458 | drm_i915_private_t *dev_priv = dev->dev_private; |
459 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 459 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
460 | int page_count = obj->size >> PAGE_SHIFT; | 460 | int page_count = obj->size >> PAGE_SHIFT; |
461 | int i; | 461 | int i; |
462 | 462 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 49c458bc6502..6421481d6222 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -260,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
260 | 260 | ||
261 | if (mode_config->num_connector) { | 261 | if (mode_config->num_connector) { |
262 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 262 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
263 | struct intel_output *intel_output = to_intel_output(connector); | 263 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
264 | 264 | ||
265 | if (intel_output->hot_plug) | 265 | if (intel_encoder->hot_plug) |
266 | (*intel_output->hot_plug) (intel_output); | 266 | (*intel_encoder->hot_plug) (intel_encoder); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | /* Just fire off a uevent and let userspace tell us what to do */ | 269 | /* Just fire off a uevent and let userspace tell us what to do */ |
@@ -444,7 +444,7 @@ i915_error_object_create(struct drm_device *dev, | |||
444 | if (src == NULL) | 444 | if (src == NULL) |
445 | return NULL; | 445 | return NULL; |
446 | 446 | ||
447 | src_priv = src->driver_private; | 447 | src_priv = to_intel_bo(src); |
448 | if (src_priv->pages == NULL) | 448 | if (src_priv->pages == NULL) |
449 | return NULL; | 449 | return NULL; |
450 | 450 | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 38110ce742a5..759c2ef72eff 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -247,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
247 | 247 | ||
248 | static bool intel_crt_detect_ddc(struct drm_connector *connector) | 248 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
249 | { | 249 | { |
250 | struct intel_output *intel_output = to_intel_output(connector); | 250 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
251 | 251 | ||
252 | /* CRT should always be at 0, but check anyway */ | 252 | /* CRT should always be at 0, but check anyway */ |
253 | if (intel_output->type != INTEL_OUTPUT_ANALOG) | 253 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) |
254 | return false; | 254 | return false; |
255 | 255 | ||
256 | return intel_ddc_probe(intel_output); | 256 | return intel_ddc_probe(intel_encoder); |
257 | } | 257 | } |
258 | 258 | ||
259 | static enum drm_connector_status | 259 | static enum drm_connector_status |
260 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) | 260 | intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) |
261 | { | 261 | { |
262 | struct drm_encoder *encoder = &intel_output->enc; | 262 | struct drm_encoder *encoder = &intel_encoder->enc; |
263 | struct drm_device *dev = encoder->dev; | 263 | struct drm_device *dev = encoder->dev; |
264 | struct drm_i915_private *dev_priv = dev->dev_private; | 264 | struct drm_i915_private *dev_priv = dev->dev_private; |
265 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 265 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -387,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) | |||
387 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) | 387 | static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) |
388 | { | 388 | { |
389 | struct drm_device *dev = connector->dev; | 389 | struct drm_device *dev = connector->dev; |
390 | struct intel_output *intel_output = to_intel_output(connector); | 390 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
391 | struct drm_encoder *encoder = &intel_output->enc; | 391 | struct drm_encoder *encoder = &intel_encoder->enc; |
392 | struct drm_crtc *crtc; | 392 | struct drm_crtc *crtc; |
393 | int dpms_mode; | 393 | int dpms_mode; |
394 | enum drm_connector_status status; | 394 | enum drm_connector_status status; |
@@ -405,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
405 | 405 | ||
406 | /* for pre-945g platforms use load detect */ | 406 | /* for pre-945g platforms use load detect */ |
407 | if (encoder->crtc && encoder->crtc->enabled) { | 407 | if (encoder->crtc && encoder->crtc->enabled) { |
408 | status = intel_crt_load_detect(encoder->crtc, intel_output); | 408 | status = intel_crt_load_detect(encoder->crtc, intel_encoder); |
409 | } else { | 409 | } else { |
410 | crtc = intel_get_load_detect_pipe(intel_output, | 410 | crtc = intel_get_load_detect_pipe(intel_encoder, |
411 | NULL, &dpms_mode); | 411 | NULL, &dpms_mode); |
412 | if (crtc) { | 412 | if (crtc) { |
413 | status = intel_crt_load_detect(crtc, intel_output); | 413 | status = intel_crt_load_detect(crtc, intel_encoder); |
414 | intel_release_load_detect_pipe(intel_output, dpms_mode); | 414 | intel_release_load_detect_pipe(intel_encoder, dpms_mode); |
415 | } else | 415 | } else |
416 | status = connector_status_unknown; | 416 | status = connector_status_unknown; |
417 | } | 417 | } |
@@ -421,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto | |||
421 | 421 | ||
422 | static void intel_crt_destroy(struct drm_connector *connector) | 422 | static void intel_crt_destroy(struct drm_connector *connector) |
423 | { | 423 | { |
424 | struct intel_output *intel_output = to_intel_output(connector); | 424 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
425 | 425 | ||
426 | intel_i2c_destroy(intel_output->ddc_bus); | 426 | intel_i2c_destroy(intel_encoder->ddc_bus); |
427 | drm_sysfs_connector_remove(connector); | 427 | drm_sysfs_connector_remove(connector); |
428 | drm_connector_cleanup(connector); | 428 | drm_connector_cleanup(connector); |
429 | kfree(connector); | 429 | kfree(connector); |
@@ -432,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
432 | static int intel_crt_get_modes(struct drm_connector *connector) | 432 | static int intel_crt_get_modes(struct drm_connector *connector) |
433 | { | 433 | { |
434 | int ret; | 434 | int ret; |
435 | struct intel_output *intel_output = to_intel_output(connector); | 435 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
436 | struct i2c_adapter *ddcbus; | 436 | struct i2c_adapter *ddcbus; |
437 | struct drm_device *dev = connector->dev; | 437 | struct drm_device *dev = connector->dev; |
438 | 438 | ||
439 | 439 | ||
440 | ret = intel_ddc_get_modes(intel_output); | 440 | ret = intel_ddc_get_modes(intel_encoder); |
441 | if (ret || !IS_G4X(dev)) | 441 | if (ret || !IS_G4X(dev)) |
442 | goto end; | 442 | goto end; |
443 | 443 | ||
444 | ddcbus = intel_output->ddc_bus; | 444 | ddcbus = intel_encoder->ddc_bus; |
445 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 445 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
446 | intel_output->ddc_bus = | 446 | intel_encoder->ddc_bus = |
447 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | 447 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); |
448 | 448 | ||
449 | if (!intel_output->ddc_bus) { | 449 | if (!intel_encoder->ddc_bus) { |
450 | intel_output->ddc_bus = ddcbus; | 450 | intel_encoder->ddc_bus = ddcbus; |
451 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | 451 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, |
452 | "DDC bus registration failed for CRTDDC_D.\n"); | 452 | "DDC bus registration failed for CRTDDC_D.\n"); |
453 | goto end; | 453 | goto end; |
454 | } | 454 | } |
455 | /* Try to get modes by GPIOD port */ | 455 | /* Try to get modes by GPIOD port */ |
456 | ret = intel_ddc_get_modes(intel_output); | 456 | ret = intel_ddc_get_modes(intel_encoder); |
457 | intel_i2c_destroy(ddcbus); | 457 | intel_i2c_destroy(ddcbus); |
458 | 458 | ||
459 | end: | 459 | end: |
@@ -506,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { | |||
506 | void intel_crt_init(struct drm_device *dev) | 506 | void intel_crt_init(struct drm_device *dev) |
507 | { | 507 | { |
508 | struct drm_connector *connector; | 508 | struct drm_connector *connector; |
509 | struct intel_output *intel_output; | 509 | struct intel_encoder *intel_encoder; |
510 | struct drm_i915_private *dev_priv = dev->dev_private; | 510 | struct drm_i915_private *dev_priv = dev->dev_private; |
511 | u32 i2c_reg; | 511 | u32 i2c_reg; |
512 | 512 | ||
513 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 513 | intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); |
514 | if (!intel_output) | 514 | if (!intel_encoder) |
515 | return; | 515 | return; |
516 | 516 | ||
517 | connector = &intel_output->base; | 517 | connector = &intel_encoder->base; |
518 | drm_connector_init(dev, &intel_output->base, | 518 | drm_connector_init(dev, &intel_encoder->base, |
519 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); | 519 | &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); |
520 | 520 | ||
521 | drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, | 521 | drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, |
522 | DRM_MODE_ENCODER_DAC); | 522 | DRM_MODE_ENCODER_DAC); |
523 | 523 | ||
524 | drm_mode_connector_attach_encoder(&intel_output->base, | 524 | drm_mode_connector_attach_encoder(&intel_encoder->base, |
525 | &intel_output->enc); | 525 | &intel_encoder->enc); |
526 | 526 | ||
527 | /* Set up the DDC bus. */ | 527 | /* Set up the DDC bus. */ |
528 | if (HAS_PCH_SPLIT(dev)) | 528 | if (HAS_PCH_SPLIT(dev)) |
@@ -533,22 +533,22 @@ void intel_crt_init(struct drm_device *dev) | |||
533 | if (dev_priv->crt_ddc_bus != 0) | 533 | if (dev_priv->crt_ddc_bus != 0) |
534 | i2c_reg = dev_priv->crt_ddc_bus; | 534 | i2c_reg = dev_priv->crt_ddc_bus; |
535 | } | 535 | } |
536 | intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); | 536 | intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); |
537 | if (!intel_output->ddc_bus) { | 537 | if (!intel_encoder->ddc_bus) { |
538 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | 538 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
539 | "failed.\n"); | 539 | "failed.\n"); |
540 | return; | 540 | return; |
541 | } | 541 | } |
542 | 542 | ||
543 | intel_output->type = INTEL_OUTPUT_ANALOG; | 543 | intel_encoder->type = INTEL_OUTPUT_ANALOG; |
544 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 544 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
545 | (1 << INTEL_ANALOG_CLONE_BIT) | | 545 | (1 << INTEL_ANALOG_CLONE_BIT) | |
546 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 546 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); |
547 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 547 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
548 | connector->interlace_allowed = 0; | 548 | connector->interlace_allowed = 0; |
549 | connector->doublescan_allowed = 0; | 549 | connector->doublescan_allowed = 0; |
550 | 550 | ||
551 | drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); | 551 | drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); |
552 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 552 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
553 | 553 | ||
554 | drm_sysfs_connector_add(connector); | 554 | drm_sysfs_connector_add(connector); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e7e753b2845f..e7356fb6c918 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -747,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) | |||
747 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { | 747 | list_for_each_entry(l_entry, &mode_config->connector_list, head) { |
748 | if (l_entry->encoder && | 748 | if (l_entry->encoder && |
749 | l_entry->encoder->crtc == crtc) { | 749 | l_entry->encoder->crtc == crtc) { |
750 | struct intel_output *intel_output = to_intel_output(l_entry); | 750 | struct intel_encoder *intel_encoder = to_intel_encoder(l_entry); |
751 | if (intel_output->type == type) | 751 | if (intel_encoder->type == type) |
752 | return true; | 752 | return true; |
753 | } | 753 | } |
754 | } | 754 | } |
755 | return false; | 755 | return false; |
756 | } | 756 | } |
757 | 757 | ||
758 | struct drm_connector * | 758 | static struct drm_connector * |
759 | intel_pipe_get_output (struct drm_crtc *crtc) | 759 | intel_pipe_get_connector (struct drm_crtc *crtc) |
760 | { | 760 | { |
761 | struct drm_device *dev = crtc->dev; | 761 | struct drm_device *dev = crtc->dev; |
762 | struct drm_mode_config *mode_config = &dev->mode_config; | 762 | struct drm_mode_config *mode_config = &dev->mode_config; |
@@ -1003,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1003 | struct drm_i915_private *dev_priv = dev->dev_private; | 1003 | struct drm_i915_private *dev_priv = dev->dev_private; |
1004 | struct drm_framebuffer *fb = crtc->fb; | 1004 | struct drm_framebuffer *fb = crtc->fb; |
1005 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1005 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1006 | struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; | 1006 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); |
1007 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1007 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1008 | int plane, i; | 1008 | int plane, i; |
1009 | u32 fbc_ctl, fbc_ctl2; | 1009 | u32 fbc_ctl, fbc_ctl2; |
@@ -1080,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1080 | struct drm_i915_private *dev_priv = dev->dev_private; | 1080 | struct drm_i915_private *dev_priv = dev->dev_private; |
1081 | struct drm_framebuffer *fb = crtc->fb; | 1081 | struct drm_framebuffer *fb = crtc->fb; |
1082 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 1082 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
1083 | struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; | 1083 | struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); |
1084 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1084 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1085 | int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : | 1085 | int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : |
1086 | DPFC_CTL_PLANEB); | 1086 | DPFC_CTL_PLANEB); |
@@ -1176,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1176 | return; | 1176 | return; |
1177 | 1177 | ||
1178 | intel_fb = to_intel_framebuffer(fb); | 1178 | intel_fb = to_intel_framebuffer(fb); |
1179 | obj_priv = intel_fb->obj->driver_private; | 1179 | obj_priv = to_intel_bo(intel_fb->obj); |
1180 | 1180 | ||
1181 | /* | 1181 | /* |
1182 | * If FBC is already on, we just have to verify that we can | 1182 | * If FBC is already on, we just have to verify that we can |
@@ -1243,7 +1243,7 @@ out_disable: | |||
1243 | static int | 1243 | static int |
1244 | intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) | 1244 | intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) |
1245 | { | 1245 | { |
1246 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1246 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1247 | u32 alignment; | 1247 | u32 alignment; |
1248 | int ret; | 1248 | int ret; |
1249 | 1249 | ||
@@ -1323,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1323 | 1323 | ||
1324 | intel_fb = to_intel_framebuffer(crtc->fb); | 1324 | intel_fb = to_intel_framebuffer(crtc->fb); |
1325 | obj = intel_fb->obj; | 1325 | obj = intel_fb->obj; |
1326 | obj_priv = obj->driver_private; | 1326 | obj_priv = to_intel_bo(obj); |
1327 | 1327 | ||
1328 | mutex_lock(&dev->struct_mutex); | 1328 | mutex_lock(&dev->struct_mutex); |
1329 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 1329 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
@@ -1401,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1401 | 1401 | ||
1402 | if (old_fb) { | 1402 | if (old_fb) { |
1403 | intel_fb = to_intel_framebuffer(old_fb); | 1403 | intel_fb = to_intel_framebuffer(old_fb); |
1404 | obj_priv = intel_fb->obj->driver_private; | 1404 | obj_priv = to_intel_bo(intel_fb->obj); |
1405 | i915_gem_object_unpin(intel_fb->obj); | 1405 | i915_gem_object_unpin(intel_fb->obj); |
1406 | } | 1406 | } |
1407 | intel_increase_pllclock(crtc, true); | 1407 | intel_increase_pllclock(crtc, true); |
@@ -2917,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2917 | int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; | 2917 | int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; |
2918 | int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; | 2918 | int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; |
2919 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; | 2919 | int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; |
2920 | int refclk, num_outputs = 0; | 2920 | int refclk, num_connectors = 0; |
2921 | intel_clock_t clock, reduced_clock; | 2921 | intel_clock_t clock, reduced_clock; |
2922 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; | 2922 | u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; |
2923 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 2923 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
@@ -2943,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2943 | drm_vblank_pre_modeset(dev, pipe); | 2943 | drm_vblank_pre_modeset(dev, pipe); |
2944 | 2944 | ||
2945 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 2945 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
2946 | struct intel_output *intel_output = to_intel_output(connector); | 2946 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
2947 | 2947 | ||
2948 | if (!connector->encoder || connector->encoder->crtc != crtc) | 2948 | if (!connector->encoder || connector->encoder->crtc != crtc) |
2949 | continue; | 2949 | continue; |
2950 | 2950 | ||
2951 | switch (intel_output->type) { | 2951 | switch (intel_encoder->type) { |
2952 | case INTEL_OUTPUT_LVDS: | 2952 | case INTEL_OUTPUT_LVDS: |
2953 | is_lvds = true; | 2953 | is_lvds = true; |
2954 | break; | 2954 | break; |
2955 | case INTEL_OUTPUT_SDVO: | 2955 | case INTEL_OUTPUT_SDVO: |
2956 | case INTEL_OUTPUT_HDMI: | 2956 | case INTEL_OUTPUT_HDMI: |
2957 | is_sdvo = true; | 2957 | is_sdvo = true; |
2958 | if (intel_output->needs_tv_clock) | 2958 | if (intel_encoder->needs_tv_clock) |
2959 | is_tv = true; | 2959 | is_tv = true; |
2960 | break; | 2960 | break; |
2961 | case INTEL_OUTPUT_DVO: | 2961 | case INTEL_OUTPUT_DVO: |
@@ -2975,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2975 | break; | 2975 | break; |
2976 | } | 2976 | } |
2977 | 2977 | ||
2978 | num_outputs++; | 2978 | num_connectors++; |
2979 | } | 2979 | } |
2980 | 2980 | ||
2981 | if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { | 2981 | if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { |
2982 | refclk = dev_priv->lvds_ssc_freq * 1000; | 2982 | refclk = dev_priv->lvds_ssc_freq * 1000; |
2983 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | 2983 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", |
2984 | refclk / 1000); | 2984 | refclk / 1000); |
@@ -3049,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3049 | if (is_edp) { | 3049 | if (is_edp) { |
3050 | struct drm_connector *edp; | 3050 | struct drm_connector *edp; |
3051 | target_clock = mode->clock; | 3051 | target_clock = mode->clock; |
3052 | edp = intel_pipe_get_output(crtc); | 3052 | edp = intel_pipe_get_connector(crtc); |
3053 | intel_edp_link_config(to_intel_output(edp), | 3053 | intel_edp_link_config(to_intel_encoder(edp), |
3054 | &lane, &link_bw); | 3054 | &lane, &link_bw); |
3055 | } else { | 3055 | } else { |
3056 | /* DP over FDI requires target mode clock | 3056 | /* DP over FDI requires target mode clock |
@@ -3231,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3231 | /* XXX: just matching BIOS for now */ | 3231 | /* XXX: just matching BIOS for now */ |
3232 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ | 3232 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
3233 | dpll |= 3; | 3233 | dpll |= 3; |
3234 | else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) | 3234 | else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) |
3235 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; | 3235 | dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; |
3236 | else | 3236 | else |
3237 | dpll |= PLL_REF_INPUT_DREFCLK; | 3237 | dpll |= PLL_REF_INPUT_DREFCLK; |
@@ -3511,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
3511 | if (!bo) | 3511 | if (!bo) |
3512 | return -ENOENT; | 3512 | return -ENOENT; |
3513 | 3513 | ||
3514 | obj_priv = bo->driver_private; | 3514 | obj_priv = to_intel_bo(bo); |
3515 | 3515 | ||
3516 | if (bo->size < width * height * 4) { | 3516 | if (bo->size < width * height * 4) { |
3517 | DRM_ERROR("buffer is to small\n"); | 3517 | DRM_ERROR("buffer is to small\n"); |
@@ -3655,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, | |||
3655 | * detection. | 3655 | * detection. |
3656 | * | 3656 | * |
3657 | * It will be up to the load-detect code to adjust the pipe as appropriate for | 3657 | * It will be up to the load-detect code to adjust the pipe as appropriate for |
3658 | * its requirements. The pipe will be connected to no other outputs. | 3658 | * its requirements. The pipe will be connected to no other encoders. |
3659 | * | 3659 | * |
3660 | * Currently this code will only succeed if there is a pipe with no outputs | 3660 | * Currently this code will only succeed if there is a pipe with no encoders |
3661 | * configured for it. In the future, it could choose to temporarily disable | 3661 | * configured for it. In the future, it could choose to temporarily disable |
3662 | * some outputs to free up a pipe for its use. | 3662 | * some outputs to free up a pipe for its use. |
3663 | * | 3663 | * |
@@ -3670,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = { | |||
3670 | 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), | 3670 | 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), |
3671 | }; | 3671 | }; |
3672 | 3672 | ||
3673 | struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, | 3673 | struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
3674 | struct drm_display_mode *mode, | 3674 | struct drm_display_mode *mode, |
3675 | int *dpms_mode) | 3675 | int *dpms_mode) |
3676 | { | 3676 | { |
3677 | struct intel_crtc *intel_crtc; | 3677 | struct intel_crtc *intel_crtc; |
3678 | struct drm_crtc *possible_crtc; | 3678 | struct drm_crtc *possible_crtc; |
3679 | struct drm_crtc *supported_crtc =NULL; | 3679 | struct drm_crtc *supported_crtc =NULL; |
3680 | struct drm_encoder *encoder = &intel_output->enc; | 3680 | struct drm_encoder *encoder = &intel_encoder->enc; |
3681 | struct drm_crtc *crtc = NULL; | 3681 | struct drm_crtc *crtc = NULL; |
3682 | struct drm_device *dev = encoder->dev; | 3682 | struct drm_device *dev = encoder->dev; |
3683 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 3683 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
@@ -3729,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, | |||
3729 | } | 3729 | } |
3730 | 3730 | ||
3731 | encoder->crtc = crtc; | 3731 | encoder->crtc = crtc; |
3732 | intel_output->base.encoder = encoder; | 3732 | intel_encoder->base.encoder = encoder; |
3733 | intel_output->load_detect_temp = true; | 3733 | intel_encoder->load_detect_temp = true; |
3734 | 3734 | ||
3735 | intel_crtc = to_intel_crtc(crtc); | 3735 | intel_crtc = to_intel_crtc(crtc); |
3736 | *dpms_mode = intel_crtc->dpms_mode; | 3736 | *dpms_mode = intel_crtc->dpms_mode; |
@@ -3755,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, | |||
3755 | return crtc; | 3755 | return crtc; |
3756 | } | 3756 | } |
3757 | 3757 | ||
3758 | void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode) | 3758 | void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode) |
3759 | { | 3759 | { |
3760 | struct drm_encoder *encoder = &intel_output->enc; | 3760 | struct drm_encoder *encoder = &intel_encoder->enc; |
3761 | struct drm_device *dev = encoder->dev; | 3761 | struct drm_device *dev = encoder->dev; |
3762 | struct drm_crtc *crtc = encoder->crtc; | 3762 | struct drm_crtc *crtc = encoder->crtc; |
3763 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 3763 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
3764 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | 3764 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
3765 | 3765 | ||
3766 | if (intel_output->load_detect_temp) { | 3766 | if (intel_encoder->load_detect_temp) { |
3767 | encoder->crtc = NULL; | 3767 | encoder->crtc = NULL; |
3768 | intel_output->base.encoder = NULL; | 3768 | intel_encoder->base.encoder = NULL; |
3769 | intel_output->load_detect_temp = false; | 3769 | intel_encoder->load_detect_temp = false; |
3770 | crtc->enabled = drm_helper_crtc_in_use(crtc); | 3770 | crtc->enabled = drm_helper_crtc_in_use(crtc); |
3771 | drm_helper_disable_unused_functions(dev); | 3771 | drm_helper_disable_unused_functions(dev); |
3772 | } | 3772 | } |
3773 | 3773 | ||
3774 | /* Switch crtc and output back off if necessary */ | 3774 | /* Switch crtc and encoder back off if necessary */ |
3775 | if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { | 3775 | if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { |
3776 | if (encoder->crtc == crtc) | 3776 | if (encoder->crtc == crtc) |
3777 | encoder_funcs->dpms(encoder, dpms_mode); | 3777 | encoder_funcs->dpms(encoder, dpms_mode); |
@@ -4156,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
4156 | work = intel_crtc->unpin_work; | 4156 | work = intel_crtc->unpin_work; |
4157 | if (work == NULL || !work->pending) { | 4157 | if (work == NULL || !work->pending) { |
4158 | if (work && !work->pending) { | 4158 | if (work && !work->pending) { |
4159 | obj_priv = work->pending_flip_obj->driver_private; | 4159 | obj_priv = to_intel_bo(work->pending_flip_obj); |
4160 | DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", | 4160 | DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", |
4161 | obj_priv, | 4161 | obj_priv, |
4162 | atomic_read(&obj_priv->pending_flip)); | 4162 | atomic_read(&obj_priv->pending_flip)); |
@@ -4181,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
4181 | 4181 | ||
4182 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4182 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4183 | 4183 | ||
4184 | obj_priv = work->pending_flip_obj->driver_private; | 4184 | obj_priv = to_intel_bo(work->pending_flip_obj); |
4185 | 4185 | ||
4186 | /* Initial scanout buffer will have a 0 pending flip count */ | 4186 | /* Initial scanout buffer will have a 0 pending flip count */ |
4187 | if ((atomic_read(&obj_priv->pending_flip) == 0) || | 4187 | if ((atomic_read(&obj_priv->pending_flip) == 0) || |
@@ -4252,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4252 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 4252 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4253 | if (ret != 0) { | 4253 | if (ret != 0) { |
4254 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | 4254 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", |
4255 | obj->driver_private); | 4255 | to_intel_bo(obj)); |
4256 | kfree(work); | 4256 | kfree(work); |
4257 | intel_crtc->unpin_work = NULL; | 4257 | intel_crtc->unpin_work = NULL; |
4258 | mutex_unlock(&dev->struct_mutex); | 4258 | mutex_unlock(&dev->struct_mutex); |
@@ -4266,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4266 | crtc->fb = fb; | 4266 | crtc->fb = fb; |
4267 | i915_gem_object_flush_write_domain(obj); | 4267 | i915_gem_object_flush_write_domain(obj); |
4268 | drm_vblank_get(dev, intel_crtc->pipe); | 4268 | drm_vblank_get(dev, intel_crtc->pipe); |
4269 | obj_priv = obj->driver_private; | 4269 | obj_priv = to_intel_bo(obj); |
4270 | atomic_inc(&obj_priv->pending_flip); | 4270 | atomic_inc(&obj_priv->pending_flip); |
4271 | work->pending_flip_obj = obj; | 4271 | work->pending_flip_obj = obj; |
4272 | 4272 | ||
@@ -4399,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) | |||
4399 | int entry = 0; | 4399 | int entry = 0; |
4400 | 4400 | ||
4401 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 4401 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
4402 | struct intel_output *intel_output = to_intel_output(connector); | 4402 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
4403 | if (type_mask & intel_output->clone_mask) | 4403 | if (type_mask & intel_encoder->clone_mask) |
4404 | index_mask |= (1 << entry); | 4404 | index_mask |= (1 << entry); |
4405 | entry++; | 4405 | entry++; |
4406 | } | 4406 | } |
@@ -4495,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
4495 | intel_tv_init(dev); | 4495 | intel_tv_init(dev); |
4496 | 4496 | ||
4497 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 4497 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
4498 | struct intel_output *intel_output = to_intel_output(connector); | 4498 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
4499 | struct drm_encoder *encoder = &intel_output->enc; | 4499 | struct drm_encoder *encoder = &intel_encoder->enc; |
4500 | 4500 | ||
4501 | encoder->possible_crtcs = intel_output->crtc_mask; | 4501 | encoder->possible_crtcs = intel_encoder->crtc_mask; |
4502 | encoder->possible_clones = intel_connector_clones(dev, | 4502 | encoder->possible_clones = intel_connector_clones(dev, |
4503 | intel_output->clone_mask); | 4503 | intel_encoder->clone_mask); |
4504 | } | 4504 | } |
4505 | } | 4505 | } |
4506 | 4506 | ||
@@ -4779,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
4779 | struct drm_i915_gem_object *obj_priv = NULL; | 4779 | struct drm_i915_gem_object *obj_priv = NULL; |
4780 | 4780 | ||
4781 | if (dev_priv->pwrctx) { | 4781 | if (dev_priv->pwrctx) { |
4782 | obj_priv = dev_priv->pwrctx->driver_private; | 4782 | obj_priv = to_intel_bo(dev_priv->pwrctx); |
4783 | } else { | 4783 | } else { |
4784 | struct drm_gem_object *pwrctx; | 4784 | struct drm_gem_object *pwrctx; |
4785 | 4785 | ||
4786 | pwrctx = intel_alloc_power_context(dev); | 4786 | pwrctx = intel_alloc_power_context(dev); |
4787 | if (pwrctx) { | 4787 | if (pwrctx) { |
4788 | dev_priv->pwrctx = pwrctx; | 4788 | dev_priv->pwrctx = pwrctx; |
4789 | obj_priv = pwrctx->driver_private; | 4789 | obj_priv = to_intel_bo(pwrctx); |
4790 | } | 4790 | } |
4791 | } | 4791 | } |
4792 | 4792 | ||
@@ -4815,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev) | |||
4815 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; | 4815 | dev_priv->display.fbc_enabled = g4x_fbc_enabled; |
4816 | dev_priv->display.enable_fbc = g4x_enable_fbc; | 4816 | dev_priv->display.enable_fbc = g4x_enable_fbc; |
4817 | dev_priv->display.disable_fbc = g4x_disable_fbc; | 4817 | dev_priv->display.disable_fbc = g4x_disable_fbc; |
4818 | } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { | 4818 | } else if (IS_I965GM(dev)) { |
4819 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; | 4819 | dev_priv->display.fbc_enabled = i8xx_fbc_enabled; |
4820 | dev_priv->display.enable_fbc = i8xx_enable_fbc; | 4820 | dev_priv->display.enable_fbc = i8xx_enable_fbc; |
4821 | dev_priv->display.disable_fbc = i8xx_disable_fbc; | 4821 | dev_priv->display.disable_fbc = i8xx_disable_fbc; |
@@ -4957,7 +4957,7 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4957 | if (dev_priv->pwrctx) { | 4957 | if (dev_priv->pwrctx) { |
4958 | struct drm_i915_gem_object *obj_priv; | 4958 | struct drm_i915_gem_object *obj_priv; |
4959 | 4959 | ||
4960 | obj_priv = dev_priv->pwrctx->driver_private; | 4960 | obj_priv = to_intel_bo(dev_priv->pwrctx); |
4961 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); | 4961 | I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); |
4962 | I915_READ(PWRCTXA); | 4962 | I915_READ(PWRCTXA); |
4963 | i915_gem_object_unpin(dev_priv->pwrctx); | 4963 | i915_gem_object_unpin(dev_priv->pwrctx); |
@@ -4978,9 +4978,9 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
4978 | */ | 4978 | */ |
4979 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) | 4979 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) |
4980 | { | 4980 | { |
4981 | struct intel_output *intel_output = to_intel_output(connector); | 4981 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
4982 | 4982 | ||
4983 | return &intel_output->enc; | 4983 | return &intel_encoder->enc; |
4984 | } | 4984 | } |
4985 | 4985 | ||
4986 | /* | 4986 | /* |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8e283f75941d..77e40cfcf216 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -55,23 +55,23 @@ struct intel_dp_priv { | |||
55 | uint8_t link_bw; | 55 | uint8_t link_bw; |
56 | uint8_t lane_count; | 56 | uint8_t lane_count; |
57 | uint8_t dpcd[4]; | 57 | uint8_t dpcd[4]; |
58 | struct intel_output *intel_output; | 58 | struct intel_encoder *intel_encoder; |
59 | struct i2c_adapter adapter; | 59 | struct i2c_adapter adapter; |
60 | struct i2c_algo_dp_aux_data algo; | 60 | struct i2c_algo_dp_aux_data algo; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static void | 63 | static void |
64 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | 64 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, |
65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | 65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); |
66 | 66 | ||
67 | static void | 67 | static void |
68 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | 68 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); |
69 | 69 | ||
70 | void | 70 | void |
71 | intel_edp_link_config (struct intel_output *intel_output, | 71 | intel_edp_link_config (struct intel_encoder *intel_encoder, |
72 | int *lane_num, int *link_bw) | 72 | int *lane_num, int *link_bw) |
73 | { | 73 | { |
74 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 74 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
75 | 75 | ||
76 | *lane_num = dp_priv->lane_count; | 76 | *lane_num = dp_priv->lane_count; |
77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | 77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) |
@@ -81,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output, | |||
81 | } | 81 | } |
82 | 82 | ||
83 | static int | 83 | static int |
84 | intel_dp_max_lane_count(struct intel_output *intel_output) | 84 | intel_dp_max_lane_count(struct intel_encoder *intel_encoder) |
85 | { | 85 | { |
86 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 86 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
87 | int max_lane_count = 4; | 87 | int max_lane_count = 4; |
88 | 88 | ||
89 | if (dp_priv->dpcd[0] >= 0x11) { | 89 | if (dp_priv->dpcd[0] >= 0x11) { |
@@ -99,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | static int | 101 | static int |
102 | intel_dp_max_link_bw(struct intel_output *intel_output) | 102 | intel_dp_max_link_bw(struct intel_encoder *intel_encoder) |
103 | { | 103 | { |
104 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 104 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
105 | int max_link_bw = dp_priv->dpcd[1]; | 105 | int max_link_bw = dp_priv->dpcd[1]; |
106 | 106 | ||
107 | switch (max_link_bw) { | 107 | switch (max_link_bw) { |
@@ -127,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw) | |||
127 | /* I think this is a fiction */ | 127 | /* I think this is a fiction */ |
128 | static int | 128 | static int |
129 | intel_dp_link_required(struct drm_device *dev, | 129 | intel_dp_link_required(struct drm_device *dev, |
130 | struct intel_output *intel_output, int pixel_clock) | 130 | struct intel_encoder *intel_encoder, int pixel_clock) |
131 | { | 131 | { |
132 | struct drm_i915_private *dev_priv = dev->dev_private; | 132 | struct drm_i915_private *dev_priv = dev->dev_private; |
133 | 133 | ||
134 | if (IS_eDP(intel_output)) | 134 | if (IS_eDP(intel_encoder)) |
135 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 135 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
136 | else | 136 | else |
137 | return pixel_clock * 3; | 137 | return pixel_clock * 3; |
@@ -141,11 +141,11 @@ static int | |||
141 | intel_dp_mode_valid(struct drm_connector *connector, | 141 | intel_dp_mode_valid(struct drm_connector *connector, |
142 | struct drm_display_mode *mode) | 142 | struct drm_display_mode *mode) |
143 | { | 143 | { |
144 | struct intel_output *intel_output = to_intel_output(connector); | 144 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
145 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); | 145 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); |
146 | int max_lanes = intel_dp_max_lane_count(intel_output); | 146 | int max_lanes = intel_dp_max_lane_count(intel_encoder); |
147 | 147 | ||
148 | if (intel_dp_link_required(connector->dev, intel_output, mode->clock) | 148 | if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) |
149 | > max_link_clock * max_lanes) | 149 | > max_link_clock * max_lanes) |
150 | return MODE_CLOCK_HIGH; | 150 | return MODE_CLOCK_HIGH; |
151 | 151 | ||
@@ -209,13 +209,13 @@ intel_hrawclk(struct drm_device *dev) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | static int | 211 | static int |
212 | intel_dp_aux_ch(struct intel_output *intel_output, | 212 | intel_dp_aux_ch(struct intel_encoder *intel_encoder, |
213 | uint8_t *send, int send_bytes, | 213 | uint8_t *send, int send_bytes, |
214 | uint8_t *recv, int recv_size) | 214 | uint8_t *recv, int recv_size) |
215 | { | 215 | { |
216 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 216 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
217 | uint32_t output_reg = dp_priv->output_reg; | 217 | uint32_t output_reg = dp_priv->output_reg; |
218 | struct drm_device *dev = intel_output->base.dev; | 218 | struct drm_device *dev = intel_encoder->base.dev; |
219 | struct drm_i915_private *dev_priv = dev->dev_private; | 219 | struct drm_i915_private *dev_priv = dev->dev_private; |
220 | uint32_t ch_ctl = output_reg + 0x10; | 220 | uint32_t ch_ctl = output_reg + 0x10; |
221 | uint32_t ch_data = ch_ctl + 4; | 221 | uint32_t ch_data = ch_ctl + 4; |
@@ -230,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
230 | * and would like to run at 2MHz. So, take the | 230 | * and would like to run at 2MHz. So, take the |
231 | * hrawclk value and divide by 2 and use that | 231 | * hrawclk value and divide by 2 and use that |
232 | */ | 232 | */ |
233 | if (IS_eDP(intel_output)) | 233 | if (IS_eDP(intel_encoder)) |
234 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | 234 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ |
235 | else if (HAS_PCH_SPLIT(dev)) | 235 | else if (HAS_PCH_SPLIT(dev)) |
236 | aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ | 236 | aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ |
@@ -313,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
313 | 313 | ||
314 | /* Write data to the aux channel in native mode */ | 314 | /* Write data to the aux channel in native mode */ |
315 | static int | 315 | static int |
316 | intel_dp_aux_native_write(struct intel_output *intel_output, | 316 | intel_dp_aux_native_write(struct intel_encoder *intel_encoder, |
317 | uint16_t address, uint8_t *send, int send_bytes) | 317 | uint16_t address, uint8_t *send, int send_bytes) |
318 | { | 318 | { |
319 | int ret; | 319 | int ret; |
@@ -330,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output, | |||
330 | memcpy(&msg[4], send, send_bytes); | 330 | memcpy(&msg[4], send, send_bytes); |
331 | msg_bytes = send_bytes + 4; | 331 | msg_bytes = send_bytes + 4; |
332 | for (;;) { | 332 | for (;;) { |
333 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); | 333 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); |
334 | if (ret < 0) | 334 | if (ret < 0) |
335 | return ret; | 335 | return ret; |
336 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | 336 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
@@ -345,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output, | |||
345 | 345 | ||
346 | /* Write a single byte to the aux channel in native mode */ | 346 | /* Write a single byte to the aux channel in native mode */ |
347 | static int | 347 | static int |
348 | intel_dp_aux_native_write_1(struct intel_output *intel_output, | 348 | intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, |
349 | uint16_t address, uint8_t byte) | 349 | uint16_t address, uint8_t byte) |
350 | { | 350 | { |
351 | return intel_dp_aux_native_write(intel_output, address, &byte, 1); | 351 | return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); |
352 | } | 352 | } |
353 | 353 | ||
354 | /* read bytes from a native aux channel */ | 354 | /* read bytes from a native aux channel */ |
355 | static int | 355 | static int |
356 | intel_dp_aux_native_read(struct intel_output *intel_output, | 356 | intel_dp_aux_native_read(struct intel_encoder *intel_encoder, |
357 | uint16_t address, uint8_t *recv, int recv_bytes) | 357 | uint16_t address, uint8_t *recv, int recv_bytes) |
358 | { | 358 | { |
359 | uint8_t msg[4]; | 359 | uint8_t msg[4]; |
@@ -372,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output, | |||
372 | reply_bytes = recv_bytes + 1; | 372 | reply_bytes = recv_bytes + 1; |
373 | 373 | ||
374 | for (;;) { | 374 | for (;;) { |
375 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, | 375 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, |
376 | reply, reply_bytes); | 376 | reply, reply_bytes); |
377 | if (ret == 0) | 377 | if (ret == 0) |
378 | return -EPROTO; | 378 | return -EPROTO; |
@@ -398,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
398 | struct intel_dp_priv *dp_priv = container_of(adapter, | 398 | struct intel_dp_priv *dp_priv = container_of(adapter, |
399 | struct intel_dp_priv, | 399 | struct intel_dp_priv, |
400 | adapter); | 400 | adapter); |
401 | struct intel_output *intel_output = dp_priv->intel_output; | 401 | struct intel_encoder *intel_encoder = dp_priv->intel_encoder; |
402 | uint16_t address = algo_data->address; | 402 | uint16_t address = algo_data->address; |
403 | uint8_t msg[5]; | 403 | uint8_t msg[5]; |
404 | uint8_t reply[2]; | 404 | uint8_t reply[2]; |
@@ -437,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
437 | } | 437 | } |
438 | 438 | ||
439 | for (;;) { | 439 | for (;;) { |
440 | ret = intel_dp_aux_ch(intel_output, | 440 | ret = intel_dp_aux_ch(intel_encoder, |
441 | msg, msg_bytes, | 441 | msg, msg_bytes, |
442 | reply, reply_bytes); | 442 | reply, reply_bytes); |
443 | if (ret < 0) { | 443 | if (ret < 0) { |
@@ -465,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static int | 467 | static int |
468 | intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | 468 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name) |
469 | { | 469 | { |
470 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 470 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
471 | 471 | ||
472 | DRM_DEBUG_KMS("i2c_init %s\n", name); | 472 | DRM_DEBUG_KMS("i2c_init %s\n", name); |
473 | dp_priv->algo.running = false; | 473 | dp_priv->algo.running = false; |
@@ -480,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | |||
480 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 480 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); |
481 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 481 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; |
482 | dp_priv->adapter.algo_data = &dp_priv->algo; | 482 | dp_priv->adapter.algo_data = &dp_priv->algo; |
483 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; | 483 | dp_priv->adapter.dev.parent = &intel_encoder->base.kdev; |
484 | 484 | ||
485 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 485 | return i2c_dp_aux_add_bus(&dp_priv->adapter); |
486 | } | 486 | } |
@@ -489,18 +489,18 @@ static bool | |||
489 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 489 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, |
490 | struct drm_display_mode *adjusted_mode) | 490 | struct drm_display_mode *adjusted_mode) |
491 | { | 491 | { |
492 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 492 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
493 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 493 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
494 | int lane_count, clock; | 494 | int lane_count, clock; |
495 | int max_lane_count = intel_dp_max_lane_count(intel_output); | 495 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); |
496 | int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; | 496 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; |
497 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 497 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
498 | 498 | ||
499 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 499 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
500 | for (clock = 0; clock <= max_clock; clock++) { | 500 | for (clock = 0; clock <= max_clock; clock++) { |
501 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; | 501 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; |
502 | 502 | ||
503 | if (intel_dp_link_required(encoder->dev, intel_output, mode->clock) | 503 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) |
504 | <= link_avail) { | 504 | <= link_avail) { |
505 | dp_priv->link_bw = bws[clock]; | 505 | dp_priv->link_bw = bws[clock]; |
506 | dp_priv->lane_count = lane_count; | 506 | dp_priv->lane_count = lane_count; |
@@ -562,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
562 | struct intel_dp_m_n m_n; | 562 | struct intel_dp_m_n m_n; |
563 | 563 | ||
564 | /* | 564 | /* |
565 | * Find the lane count in the intel_output private | 565 | * Find the lane count in the intel_encoder private |
566 | */ | 566 | */ |
567 | list_for_each_entry(connector, &mode_config->connector_list, head) { | 567 | list_for_each_entry(connector, &mode_config->connector_list, head) { |
568 | struct intel_output *intel_output = to_intel_output(connector); | 568 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
569 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 569 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
570 | 570 | ||
571 | if (!connector->encoder || connector->encoder->crtc != crtc) | 571 | if (!connector->encoder || connector->encoder->crtc != crtc) |
572 | continue; | 572 | continue; |
573 | 573 | ||
574 | if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { | 574 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { |
575 | lane_count = dp_priv->lane_count; | 575 | lane_count = dp_priv->lane_count; |
576 | break; | 576 | break; |
577 | } | 577 | } |
@@ -626,9 +626,9 @@ static void | |||
626 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | 626 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, |
627 | struct drm_display_mode *adjusted_mode) | 627 | struct drm_display_mode *adjusted_mode) |
628 | { | 628 | { |
629 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 629 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
630 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 630 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
631 | struct drm_crtc *crtc = intel_output->enc.crtc; | 631 | struct drm_crtc *crtc = intel_encoder->enc.crtc; |
632 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 632 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
633 | 633 | ||
634 | dp_priv->DP = (DP_LINK_TRAIN_OFF | | 634 | dp_priv->DP = (DP_LINK_TRAIN_OFF | |
@@ -667,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
667 | if (intel_crtc->pipe == 1) | 667 | if (intel_crtc->pipe == 1) |
668 | dp_priv->DP |= DP_PIPEB_SELECT; | 668 | dp_priv->DP |= DP_PIPEB_SELECT; |
669 | 669 | ||
670 | if (IS_eDP(intel_output)) { | 670 | if (IS_eDP(intel_encoder)) { |
671 | /* don't miss out required setting for eDP */ | 671 | /* don't miss out required setting for eDP */ |
672 | dp_priv->DP |= DP_PLL_ENABLE; | 672 | dp_priv->DP |= DP_PLL_ENABLE; |
673 | if (adjusted_mode->clock < 200000) | 673 | if (adjusted_mode->clock < 200000) |
@@ -702,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) | |||
702 | static void | 702 | static void |
703 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 703 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
704 | { | 704 | { |
705 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 705 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
706 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 706 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
707 | struct drm_device *dev = intel_output->base.dev; | 707 | struct drm_device *dev = intel_encoder->base.dev; |
708 | struct drm_i915_private *dev_priv = dev->dev_private; | 708 | struct drm_i915_private *dev_priv = dev->dev_private; |
709 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 709 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); |
710 | 710 | ||
711 | if (mode != DRM_MODE_DPMS_ON) { | 711 | if (mode != DRM_MODE_DPMS_ON) { |
712 | if (dp_reg & DP_PORT_EN) { | 712 | if (dp_reg & DP_PORT_EN) { |
713 | intel_dp_link_down(intel_output, dp_priv->DP); | 713 | intel_dp_link_down(intel_encoder, dp_priv->DP); |
714 | if (IS_eDP(intel_output)) | 714 | if (IS_eDP(intel_encoder)) |
715 | ironlake_edp_backlight_off(dev); | 715 | ironlake_edp_backlight_off(dev); |
716 | } | 716 | } |
717 | } else { | 717 | } else { |
718 | if (!(dp_reg & DP_PORT_EN)) { | 718 | if (!(dp_reg & DP_PORT_EN)) { |
719 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 719 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); |
720 | if (IS_eDP(intel_output)) | 720 | if (IS_eDP(intel_encoder)) |
721 | ironlake_edp_backlight_on(dev); | 721 | ironlake_edp_backlight_on(dev); |
722 | } | 722 | } |
723 | } | 723 | } |
@@ -729,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
729 | * link status information | 729 | * link status information |
730 | */ | 730 | */ |
731 | static bool | 731 | static bool |
732 | intel_dp_get_link_status(struct intel_output *intel_output, | 732 | intel_dp_get_link_status(struct intel_encoder *intel_encoder, |
733 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | 733 | uint8_t link_status[DP_LINK_STATUS_SIZE]) |
734 | { | 734 | { |
735 | int ret; | 735 | int ret; |
736 | 736 | ||
737 | ret = intel_dp_aux_native_read(intel_output, | 737 | ret = intel_dp_aux_native_read(intel_encoder, |
738 | DP_LANE0_1_STATUS, | 738 | DP_LANE0_1_STATUS, |
739 | link_status, DP_LINK_STATUS_SIZE); | 739 | link_status, DP_LINK_STATUS_SIZE); |
740 | if (ret != DP_LINK_STATUS_SIZE) | 740 | if (ret != DP_LINK_STATUS_SIZE) |
@@ -752,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | |||
752 | static void | 752 | static void |
753 | intel_dp_save(struct drm_connector *connector) | 753 | intel_dp_save(struct drm_connector *connector) |
754 | { | 754 | { |
755 | struct intel_output *intel_output = to_intel_output(connector); | 755 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
756 | struct drm_device *dev = intel_output->base.dev; | 756 | struct drm_device *dev = intel_encoder->base.dev; |
757 | struct drm_i915_private *dev_priv = dev->dev_private; | 757 | struct drm_i915_private *dev_priv = dev->dev_private; |
758 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 758 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
759 | 759 | ||
760 | dp_priv->save_DP = I915_READ(dp_priv->output_reg); | 760 | dp_priv->save_DP = I915_READ(dp_priv->output_reg); |
761 | intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, | 761 | intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET, |
762 | dp_priv->save_link_configuration, | 762 | dp_priv->save_link_configuration, |
763 | sizeof (dp_priv->save_link_configuration)); | 763 | sizeof (dp_priv->save_link_configuration)); |
764 | } | 764 | } |
@@ -825,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
825 | } | 825 | } |
826 | 826 | ||
827 | static void | 827 | static void |
828 | intel_get_adjust_train(struct intel_output *intel_output, | 828 | intel_get_adjust_train(struct intel_encoder *intel_encoder, |
829 | uint8_t link_status[DP_LINK_STATUS_SIZE], | 829 | uint8_t link_status[DP_LINK_STATUS_SIZE], |
830 | int lane_count, | 830 | int lane_count, |
831 | uint8_t train_set[4]) | 831 | uint8_t train_set[4]) |
@@ -942,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | |||
942 | } | 942 | } |
943 | 943 | ||
944 | static bool | 944 | static bool |
945 | intel_dp_set_link_train(struct intel_output *intel_output, | 945 | intel_dp_set_link_train(struct intel_encoder *intel_encoder, |
946 | uint32_t dp_reg_value, | 946 | uint32_t dp_reg_value, |
947 | uint8_t dp_train_pat, | 947 | uint8_t dp_train_pat, |
948 | uint8_t train_set[4], | 948 | uint8_t train_set[4], |
949 | bool first) | 949 | bool first) |
950 | { | 950 | { |
951 | struct drm_device *dev = intel_output->base.dev; | 951 | struct drm_device *dev = intel_encoder->base.dev; |
952 | struct drm_i915_private *dev_priv = dev->dev_private; | 952 | struct drm_i915_private *dev_priv = dev->dev_private; |
953 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 953 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
954 | int ret; | 954 | int ret; |
955 | 955 | ||
956 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | 956 | I915_WRITE(dp_priv->output_reg, dp_reg_value); |
@@ -958,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output, | |||
958 | if (first) | 958 | if (first) |
959 | intel_wait_for_vblank(dev); | 959 | intel_wait_for_vblank(dev); |
960 | 960 | ||
961 | intel_dp_aux_native_write_1(intel_output, | 961 | intel_dp_aux_native_write_1(intel_encoder, |
962 | DP_TRAINING_PATTERN_SET, | 962 | DP_TRAINING_PATTERN_SET, |
963 | dp_train_pat); | 963 | dp_train_pat); |
964 | 964 | ||
965 | ret = intel_dp_aux_native_write(intel_output, | 965 | ret = intel_dp_aux_native_write(intel_encoder, |
966 | DP_TRAINING_LANE0_SET, train_set, 4); | 966 | DP_TRAINING_LANE0_SET, train_set, 4); |
967 | if (ret != 4) | 967 | if (ret != 4) |
968 | return false; | 968 | return false; |
@@ -971,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output, | |||
971 | } | 971 | } |
972 | 972 | ||
973 | static void | 973 | static void |
974 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | 974 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, |
975 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | 975 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) |
976 | { | 976 | { |
977 | struct drm_device *dev = intel_output->base.dev; | 977 | struct drm_device *dev = intel_encoder->base.dev; |
978 | struct drm_i915_private *dev_priv = dev->dev_private; | 978 | struct drm_i915_private *dev_priv = dev->dev_private; |
979 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 979 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
980 | uint8_t train_set[4]; | 980 | uint8_t train_set[4]; |
981 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 981 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
982 | int i; | 982 | int i; |
@@ -987,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
987 | int tries; | 987 | int tries; |
988 | 988 | ||
989 | /* Write the link configuration data */ | 989 | /* Write the link configuration data */ |
990 | intel_dp_aux_native_write(intel_output, 0x100, | 990 | intel_dp_aux_native_write(intel_encoder, 0x100, |
991 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 991 | link_configuration, DP_LINK_CONFIGURATION_SIZE); |
992 | 992 | ||
993 | DP |= DP_PORT_EN; | 993 | DP |= DP_PORT_EN; |
@@ -1001,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
1001 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1001 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); |
1002 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1002 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1003 | 1003 | ||
1004 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, | 1004 | if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1, |
1005 | DP_TRAINING_PATTERN_1, train_set, first)) | 1005 | DP_TRAINING_PATTERN_1, train_set, first)) |
1006 | break; | 1006 | break; |
1007 | first = false; | 1007 | first = false; |
1008 | /* Set training pattern 1 */ | 1008 | /* Set training pattern 1 */ |
1009 | 1009 | ||
1010 | udelay(100); | 1010 | udelay(100); |
1011 | if (!intel_dp_get_link_status(intel_output, link_status)) | 1011 | if (!intel_dp_get_link_status(intel_encoder, link_status)) |
1012 | break; | 1012 | break; |
1013 | 1013 | ||
1014 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | 1014 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { |
@@ -1033,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
1033 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1033 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1034 | 1034 | ||
1035 | /* Compute new train_set as requested by target */ | 1035 | /* Compute new train_set as requested by target */ |
1036 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | 1036 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | /* channel equalization */ | 1039 | /* channel equalization */ |
@@ -1045,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
1045 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1045 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1046 | 1046 | ||
1047 | /* channel eq pattern */ | 1047 | /* channel eq pattern */ |
1048 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, | 1048 | if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2, |
1049 | DP_TRAINING_PATTERN_2, train_set, | 1049 | DP_TRAINING_PATTERN_2, train_set, |
1050 | false)) | 1050 | false)) |
1051 | break; | 1051 | break; |
1052 | 1052 | ||
1053 | udelay(400); | 1053 | udelay(400); |
1054 | if (!intel_dp_get_link_status(intel_output, link_status)) | 1054 | if (!intel_dp_get_link_status(intel_encoder, link_status)) |
1055 | break; | 1055 | break; |
1056 | 1056 | ||
1057 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | 1057 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { |
@@ -1064,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | |||
1064 | break; | 1064 | break; |
1065 | 1065 | ||
1066 | /* Compute new train_set as requested by target */ | 1066 | /* Compute new train_set as requested by target */ |
1067 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | 1067 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); |
1068 | ++tries; | 1068 | ++tries; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); | 1071 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); |
1072 | POSTING_READ(dp_priv->output_reg); | 1072 | POSTING_READ(dp_priv->output_reg); |
1073 | intel_dp_aux_native_write_1(intel_output, | 1073 | intel_dp_aux_native_write_1(intel_encoder, |
1074 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1074 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static void | 1077 | static void |
1078 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | 1078 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) |
1079 | { | 1079 | { |
1080 | struct drm_device *dev = intel_output->base.dev; | 1080 | struct drm_device *dev = intel_encoder->base.dev; |
1081 | struct drm_i915_private *dev_priv = dev->dev_private; | 1081 | struct drm_i915_private *dev_priv = dev->dev_private; |
1082 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1082 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1083 | 1083 | ||
1084 | DRM_DEBUG_KMS("\n"); | 1084 | DRM_DEBUG_KMS("\n"); |
1085 | 1085 | ||
1086 | if (IS_eDP(intel_output)) { | 1086 | if (IS_eDP(intel_encoder)) { |
1087 | DP &= ~DP_PLL_ENABLE; | 1087 | DP &= ~DP_PLL_ENABLE; |
1088 | I915_WRITE(dp_priv->output_reg, DP); | 1088 | I915_WRITE(dp_priv->output_reg, DP); |
1089 | POSTING_READ(dp_priv->output_reg); | 1089 | POSTING_READ(dp_priv->output_reg); |
@@ -1096,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | |||
1096 | 1096 | ||
1097 | udelay(17000); | 1097 | udelay(17000); |
1098 | 1098 | ||
1099 | if (IS_eDP(intel_output)) | 1099 | if (IS_eDP(intel_encoder)) |
1100 | DP |= DP_LINK_TRAIN_OFF; | 1100 | DP |= DP_LINK_TRAIN_OFF; |
1101 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1101 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); |
1102 | POSTING_READ(dp_priv->output_reg); | 1102 | POSTING_READ(dp_priv->output_reg); |
@@ -1105,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | |||
1105 | static void | 1105 | static void |
1106 | intel_dp_restore(struct drm_connector *connector) | 1106 | intel_dp_restore(struct drm_connector *connector) |
1107 | { | 1107 | { |
1108 | struct intel_output *intel_output = to_intel_output(connector); | 1108 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1109 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1109 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1110 | 1110 | ||
1111 | if (dp_priv->save_DP & DP_PORT_EN) | 1111 | if (dp_priv->save_DP & DP_PORT_EN) |
1112 | intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); | 1112 | intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration); |
1113 | else | 1113 | else |
1114 | intel_dp_link_down(intel_output, dp_priv->save_DP); | 1114 | intel_dp_link_down(intel_encoder, dp_priv->save_DP); |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | /* | 1117 | /* |
@@ -1124,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector) | |||
1124 | */ | 1124 | */ |
1125 | 1125 | ||
1126 | static void | 1126 | static void |
1127 | intel_dp_check_link_status(struct intel_output *intel_output) | 1127 | intel_dp_check_link_status(struct intel_encoder *intel_encoder) |
1128 | { | 1128 | { |
1129 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1129 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1130 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1130 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1131 | 1131 | ||
1132 | if (!intel_output->enc.crtc) | 1132 | if (!intel_encoder->enc.crtc) |
1133 | return; | 1133 | return; |
1134 | 1134 | ||
1135 | if (!intel_dp_get_link_status(intel_output, link_status)) { | 1135 | if (!intel_dp_get_link_status(intel_encoder, link_status)) { |
1136 | intel_dp_link_down(intel_output, dp_priv->DP); | 1136 | intel_dp_link_down(intel_encoder, dp_priv->DP); |
1137 | return; | 1137 | return; |
1138 | } | 1138 | } |
1139 | 1139 | ||
1140 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | 1140 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) |
1141 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | 1141 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | static enum drm_connector_status | 1144 | static enum drm_connector_status |
1145 | ironlake_dp_detect(struct drm_connector *connector) | 1145 | ironlake_dp_detect(struct drm_connector *connector) |
1146 | { | 1146 | { |
1147 | struct intel_output *intel_output = to_intel_output(connector); | 1147 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1148 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1148 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1149 | enum drm_connector_status status; | 1149 | enum drm_connector_status status; |
1150 | 1150 | ||
1151 | status = connector_status_disconnected; | 1151 | status = connector_status_disconnected; |
1152 | if (intel_dp_aux_native_read(intel_output, | 1152 | if (intel_dp_aux_native_read(intel_encoder, |
1153 | 0x000, dp_priv->dpcd, | 1153 | 0x000, dp_priv->dpcd, |
1154 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1154 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) |
1155 | { | 1155 | { |
@@ -1168,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1168 | static enum drm_connector_status | 1168 | static enum drm_connector_status |
1169 | intel_dp_detect(struct drm_connector *connector) | 1169 | intel_dp_detect(struct drm_connector *connector) |
1170 | { | 1170 | { |
1171 | struct intel_output *intel_output = to_intel_output(connector); | 1171 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1172 | struct drm_device *dev = intel_output->base.dev; | 1172 | struct drm_device *dev = intel_encoder->base.dev; |
1173 | struct drm_i915_private *dev_priv = dev->dev_private; | 1173 | struct drm_i915_private *dev_priv = dev->dev_private; |
1174 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1174 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1175 | uint32_t temp, bit; | 1175 | uint32_t temp, bit; |
1176 | enum drm_connector_status status; | 1176 | enum drm_connector_status status; |
1177 | 1177 | ||
@@ -1210,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector) | |||
1210 | return connector_status_disconnected; | 1210 | return connector_status_disconnected; |
1211 | 1211 | ||
1212 | status = connector_status_disconnected; | 1212 | status = connector_status_disconnected; |
1213 | if (intel_dp_aux_native_read(intel_output, | 1213 | if (intel_dp_aux_native_read(intel_encoder, |
1214 | 0x000, dp_priv->dpcd, | 1214 | 0x000, dp_priv->dpcd, |
1215 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1215 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) |
1216 | { | 1216 | { |
@@ -1222,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector) | |||
1222 | 1222 | ||
1223 | static int intel_dp_get_modes(struct drm_connector *connector) | 1223 | static int intel_dp_get_modes(struct drm_connector *connector) |
1224 | { | 1224 | { |
1225 | struct intel_output *intel_output = to_intel_output(connector); | 1225 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1226 | struct drm_device *dev = intel_output->base.dev; | 1226 | struct drm_device *dev = intel_encoder->base.dev; |
1227 | struct drm_i915_private *dev_priv = dev->dev_private; | 1227 | struct drm_i915_private *dev_priv = dev->dev_private; |
1228 | int ret; | 1228 | int ret; |
1229 | 1229 | ||
1230 | /* We should parse the EDID data and find out if it has an audio sink | 1230 | /* We should parse the EDID data and find out if it has an audio sink |
1231 | */ | 1231 | */ |
1232 | 1232 | ||
1233 | ret = intel_ddc_get_modes(intel_output); | 1233 | ret = intel_ddc_get_modes(intel_encoder); |
1234 | if (ret) | 1234 | if (ret) |
1235 | return ret; | 1235 | return ret; |
1236 | 1236 | ||
1237 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1237 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
1238 | if (IS_eDP(intel_output)) { | 1238 | if (IS_eDP(intel_encoder)) { |
1239 | if (dev_priv->panel_fixed_mode != NULL) { | 1239 | if (dev_priv->panel_fixed_mode != NULL) { |
1240 | struct drm_display_mode *mode; | 1240 | struct drm_display_mode *mode; |
1241 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1241 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
@@ -1249,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1249 | static void | 1249 | static void |
1250 | intel_dp_destroy (struct drm_connector *connector) | 1250 | intel_dp_destroy (struct drm_connector *connector) |
1251 | { | 1251 | { |
1252 | struct intel_output *intel_output = to_intel_output(connector); | 1252 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1253 | 1253 | ||
1254 | if (intel_output->i2c_bus) | 1254 | if (intel_encoder->i2c_bus) |
1255 | intel_i2c_destroy(intel_output->i2c_bus); | 1255 | intel_i2c_destroy(intel_encoder->i2c_bus); |
1256 | drm_sysfs_connector_remove(connector); | 1256 | drm_sysfs_connector_remove(connector); |
1257 | drm_connector_cleanup(connector); | 1257 | drm_connector_cleanup(connector); |
1258 | kfree(intel_output); | 1258 | kfree(intel_encoder); |
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1261 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
@@ -1291,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = { | |||
1291 | }; | 1291 | }; |
1292 | 1292 | ||
1293 | void | 1293 | void |
1294 | intel_dp_hot_plug(struct intel_output *intel_output) | 1294 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
1295 | { | 1295 | { |
1296 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | 1296 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; |
1297 | 1297 | ||
1298 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1298 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) |
1299 | intel_dp_check_link_status(intel_output); | 1299 | intel_dp_check_link_status(intel_encoder); |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | void | 1302 | void |
@@ -1304,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1304 | { | 1304 | { |
1305 | struct drm_i915_private *dev_priv = dev->dev_private; | 1305 | struct drm_i915_private *dev_priv = dev->dev_private; |
1306 | struct drm_connector *connector; | 1306 | struct drm_connector *connector; |
1307 | struct intel_output *intel_output; | 1307 | struct intel_encoder *intel_encoder; |
1308 | struct intel_dp_priv *dp_priv; | 1308 | struct intel_dp_priv *dp_priv; |
1309 | const char *name = NULL; | 1309 | const char *name = NULL; |
1310 | 1310 | ||
1311 | intel_output = kcalloc(sizeof(struct intel_output) + | 1311 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + |
1312 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1312 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); |
1313 | if (!intel_output) | 1313 | if (!intel_encoder) |
1314 | return; | 1314 | return; |
1315 | 1315 | ||
1316 | dp_priv = (struct intel_dp_priv *)(intel_output + 1); | 1316 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); |
1317 | 1317 | ||
1318 | connector = &intel_output->base; | 1318 | connector = &intel_encoder->base; |
1319 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, | 1319 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, |
1320 | DRM_MODE_CONNECTOR_DisplayPort); | 1320 | DRM_MODE_CONNECTOR_DisplayPort); |
1321 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | 1321 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); |
1322 | 1322 | ||
1323 | if (output_reg == DP_A) | 1323 | if (output_reg == DP_A) |
1324 | intel_output->type = INTEL_OUTPUT_EDP; | 1324 | intel_encoder->type = INTEL_OUTPUT_EDP; |
1325 | else | 1325 | else |
1326 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | 1326 | intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; |
1327 | 1327 | ||
1328 | if (output_reg == DP_B || output_reg == PCH_DP_B) | 1328 | if (output_reg == DP_B || output_reg == PCH_DP_B) |
1329 | intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); | 1329 | intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); |
1330 | else if (output_reg == DP_C || output_reg == PCH_DP_C) | 1330 | else if (output_reg == DP_C || output_reg == PCH_DP_C) |
1331 | intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); | 1331 | intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); |
1332 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1332 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
1333 | intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1333 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
1334 | 1334 | ||
1335 | if (IS_eDP(intel_output)) | 1335 | if (IS_eDP(intel_encoder)) |
1336 | intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1336 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
1337 | 1337 | ||
1338 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 1338 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1339 | connector->interlace_allowed = true; | 1339 | connector->interlace_allowed = true; |
1340 | connector->doublescan_allowed = 0; | 1340 | connector->doublescan_allowed = 0; |
1341 | 1341 | ||
1342 | dp_priv->intel_output = intel_output; | 1342 | dp_priv->intel_encoder = intel_encoder; |
1343 | dp_priv->output_reg = output_reg; | 1343 | dp_priv->output_reg = output_reg; |
1344 | dp_priv->has_audio = false; | 1344 | dp_priv->has_audio = false; |
1345 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | 1345 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; |
1346 | intel_output->dev_priv = dp_priv; | 1346 | intel_encoder->dev_priv = dp_priv; |
1347 | 1347 | ||
1348 | drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, | 1348 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, |
1349 | DRM_MODE_ENCODER_TMDS); | 1349 | DRM_MODE_ENCODER_TMDS); |
1350 | drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); | 1350 | drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); |
1351 | 1351 | ||
1352 | drm_mode_connector_attach_encoder(&intel_output->base, | 1352 | drm_mode_connector_attach_encoder(&intel_encoder->base, |
1353 | &intel_output->enc); | 1353 | &intel_encoder->enc); |
1354 | drm_sysfs_connector_add(connector); | 1354 | drm_sysfs_connector_add(connector); |
1355 | 1355 | ||
1356 | /* Set up the DDC bus. */ | 1356 | /* Set up the DDC bus. */ |
@@ -1378,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1378 | break; | 1378 | break; |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | intel_dp_i2c_init(intel_output, name); | 1381 | intel_dp_i2c_init(intel_encoder, name); |
1382 | 1382 | ||
1383 | intel_output->ddc_bus = &dp_priv->adapter; | 1383 | intel_encoder->ddc_bus = &dp_priv->adapter; |
1384 | intel_output->hot_plug = intel_dp_hot_plug; | 1384 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1385 | 1385 | ||
1386 | if (output_reg == DP_A) { | 1386 | if (output_reg == DP_A) { |
1387 | /* initialize panel mode from VBT if available for eDP */ | 1387 | /* initialize panel mode from VBT if available for eDP */ |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3a467ca57857..e30253755f12 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -95,7 +95,7 @@ struct intel_framebuffer { | |||
95 | }; | 95 | }; |
96 | 96 | ||
97 | 97 | ||
98 | struct intel_output { | 98 | struct intel_encoder { |
99 | struct drm_connector base; | 99 | struct drm_connector base; |
100 | 100 | ||
101 | struct drm_encoder enc; | 101 | struct drm_encoder enc; |
@@ -105,7 +105,7 @@ struct intel_output { | |||
105 | bool load_detect_temp; | 105 | bool load_detect_temp; |
106 | bool needs_tv_clock; | 106 | bool needs_tv_clock; |
107 | void *dev_priv; | 107 | void *dev_priv; |
108 | void (*hot_plug)(struct intel_output *); | 108 | void (*hot_plug)(struct intel_encoder *); |
109 | int crtc_mask; | 109 | int crtc_mask; |
110 | int clone_mask; | 110 | int clone_mask; |
111 | }; | 111 | }; |
@@ -152,15 +152,15 @@ struct intel_crtc { | |||
152 | }; | 152 | }; |
153 | 153 | ||
154 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 154 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
155 | #define to_intel_output(x) container_of(x, struct intel_output, base) | 155 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) |
156 | #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) | 156 | #define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) |
157 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 157 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
158 | 158 | ||
159 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, | 159 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
160 | const char *name); | 160 | const char *name); |
161 | void intel_i2c_destroy(struct i2c_adapter *adapter); | 161 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
162 | int intel_ddc_get_modes(struct intel_output *intel_output); | 162 | int intel_ddc_get_modes(struct intel_encoder *intel_encoder); |
163 | extern bool intel_ddc_probe(struct intel_output *intel_output); | 163 | extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); |
164 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); | 164 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); |
165 | void intel_i2c_reset_gmbus(struct drm_device *dev); | 165 | void intel_i2c_reset_gmbus(struct drm_device *dev); |
166 | 166 | ||
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); | |||
175 | void | 175 | void |
176 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | 176 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, |
177 | struct drm_display_mode *adjusted_mode); | 177 | struct drm_display_mode *adjusted_mode); |
178 | extern void intel_edp_link_config (struct intel_output *, int *, int *); | 178 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
179 | 179 | ||
180 | 180 | ||
181 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | 181 | extern int intel_panel_fitter_pipe (struct drm_device *dev); |
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | |||
191 | struct drm_file *file_priv); | 191 | struct drm_file *file_priv); |
192 | extern void intel_wait_for_vblank(struct drm_device *dev); | 192 | extern void intel_wait_for_vblank(struct drm_device *dev); |
193 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 193 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
194 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, | 194 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
195 | struct drm_display_mode *mode, | 195 | struct drm_display_mode *mode, |
196 | int *dpms_mode); | 196 | int *dpms_mode); |
197 | extern void intel_release_load_detect_pipe(struct intel_output *intel_output, | 197 | extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, |
198 | int dpms_mode); | 198 | int dpms_mode); |
199 | 199 | ||
200 | extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); | 200 | extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 0427ca5a2514..ebf213c96b9c 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -80,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = { | |||
80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
81 | { | 81 | { |
82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
83 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 83 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
84 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 84 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
85 | u32 dvo_reg = dvo->dvo_reg; | 85 | u32 dvo_reg = dvo->dvo_reg; |
86 | u32 temp = I915_READ(dvo_reg); | 86 | u32 temp = I915_READ(dvo_reg); |
87 | 87 | ||
@@ -99,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | |||
99 | static void intel_dvo_save(struct drm_connector *connector) | 99 | static void intel_dvo_save(struct drm_connector *connector) |
100 | { | 100 | { |
101 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 101 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
102 | struct intel_output *intel_output = to_intel_output(connector); | 102 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
103 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 103 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
104 | 104 | ||
105 | /* Each output should probably just save the registers it touches, | 105 | /* Each output should probably just save the registers it touches, |
106 | * but for now, use more overkill. | 106 | * but for now, use more overkill. |
@@ -115,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector) | |||
115 | static void intel_dvo_restore(struct drm_connector *connector) | 115 | static void intel_dvo_restore(struct drm_connector *connector) |
116 | { | 116 | { |
117 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 117 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
118 | struct intel_output *intel_output = to_intel_output(connector); | 118 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
119 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 119 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
120 | 120 | ||
121 | dvo->dev_ops->restore(dvo); | 121 | dvo->dev_ops->restore(dvo); |
122 | 122 | ||
@@ -128,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector) | |||
128 | static int intel_dvo_mode_valid(struct drm_connector *connector, | 128 | static int intel_dvo_mode_valid(struct drm_connector *connector, |
129 | struct drm_display_mode *mode) | 129 | struct drm_display_mode *mode) |
130 | { | 130 | { |
131 | struct intel_output *intel_output = to_intel_output(connector); | 131 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
132 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 132 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
133 | 133 | ||
134 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 134 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
135 | return MODE_NO_DBLESCAN; | 135 | return MODE_NO_DBLESCAN; |
@@ -150,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | |||
150 | struct drm_display_mode *mode, | 150 | struct drm_display_mode *mode, |
151 | struct drm_display_mode *adjusted_mode) | 151 | struct drm_display_mode *adjusted_mode) |
152 | { | 152 | { |
153 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 153 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
154 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 154 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
155 | 155 | ||
156 | /* If we have timings from the BIOS for the panel, put them in | 156 | /* If we have timings from the BIOS for the panel, put them in |
157 | * to the adjusted mode. The CRTC will be set up for this mode, | 157 | * to the adjusted mode. The CRTC will be set up for this mode, |
@@ -186,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
186 | struct drm_device *dev = encoder->dev; | 186 | struct drm_device *dev = encoder->dev; |
187 | struct drm_i915_private *dev_priv = dev->dev_private; | 187 | struct drm_i915_private *dev_priv = dev->dev_private; |
188 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 188 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
189 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 189 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
190 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 190 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
191 | int pipe = intel_crtc->pipe; | 191 | int pipe = intel_crtc->pipe; |
192 | u32 dvo_val; | 192 | u32 dvo_val; |
193 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; | 193 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; |
@@ -241,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
241 | */ | 241 | */ |
242 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 242 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
243 | { | 243 | { |
244 | struct intel_output *intel_output = to_intel_output(connector); | 244 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
245 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 245 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
246 | 246 | ||
247 | return dvo->dev_ops->detect(dvo); | 247 | return dvo->dev_ops->detect(dvo); |
248 | } | 248 | } |
249 | 249 | ||
250 | static int intel_dvo_get_modes(struct drm_connector *connector) | 250 | static int intel_dvo_get_modes(struct drm_connector *connector) |
251 | { | 251 | { |
252 | struct intel_output *intel_output = to_intel_output(connector); | 252 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
253 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 253 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
254 | 254 | ||
255 | /* We should probably have an i2c driver get_modes function for those | 255 | /* We should probably have an i2c driver get_modes function for those |
256 | * devices which will have a fixed set of modes determined by the chip | 256 | * devices which will have a fixed set of modes determined by the chip |
257 | * (TV-out, for example), but for now with just TMDS and LVDS, | 257 | * (TV-out, for example), but for now with just TMDS and LVDS, |
258 | * that's not the case. | 258 | * that's not the case. |
259 | */ | 259 | */ |
260 | intel_ddc_get_modes(intel_output); | 260 | intel_ddc_get_modes(intel_encoder); |
261 | if (!list_empty(&connector->probed_modes)) | 261 | if (!list_empty(&connector->probed_modes)) |
262 | return 1; | 262 | return 1; |
263 | 263 | ||
@@ -275,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
275 | 275 | ||
276 | static void intel_dvo_destroy (struct drm_connector *connector) | 276 | static void intel_dvo_destroy (struct drm_connector *connector) |
277 | { | 277 | { |
278 | struct intel_output *intel_output = to_intel_output(connector); | 278 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
279 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 279 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
280 | 280 | ||
281 | if (dvo) { | 281 | if (dvo) { |
282 | if (dvo->dev_ops->destroy) | 282 | if (dvo->dev_ops->destroy) |
@@ -286,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector) | |||
286 | /* no need, in i830_dvoices[] now */ | 286 | /* no need, in i830_dvoices[] now */ |
287 | //kfree(dvo); | 287 | //kfree(dvo); |
288 | } | 288 | } |
289 | if (intel_output->i2c_bus) | 289 | if (intel_encoder->i2c_bus) |
290 | intel_i2c_destroy(intel_output->i2c_bus); | 290 | intel_i2c_destroy(intel_encoder->i2c_bus); |
291 | if (intel_output->ddc_bus) | 291 | if (intel_encoder->ddc_bus) |
292 | intel_i2c_destroy(intel_output->ddc_bus); | 292 | intel_i2c_destroy(intel_encoder->ddc_bus); |
293 | drm_sysfs_connector_remove(connector); | 293 | drm_sysfs_connector_remove(connector); |
294 | drm_connector_cleanup(connector); | 294 | drm_connector_cleanup(connector); |
295 | kfree(intel_output); | 295 | kfree(intel_encoder); |
296 | } | 296 | } |
297 | 297 | ||
298 | #ifdef RANDR_GET_CRTC_INTERFACE | 298 | #ifdef RANDR_GET_CRTC_INTERFACE |
@@ -300,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) | |||
300 | { | 300 | { |
301 | struct drm_device *dev = connector->dev; | 301 | struct drm_device *dev = connector->dev; |
302 | struct drm_i915_private *dev_priv = dev->dev_private; | 302 | struct drm_i915_private *dev_priv = dev->dev_private; |
303 | struct intel_output *intel_output = to_intel_output(connector); | 303 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
304 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 304 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
305 | int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); | 305 | int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); |
306 | 306 | ||
307 | return intel_pipe_to_crtc(pScrn, pipe); | 307 | return intel_pipe_to_crtc(pScrn, pipe); |
@@ -352,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
352 | { | 352 | { |
353 | struct drm_device *dev = connector->dev; | 353 | struct drm_device *dev = connector->dev; |
354 | struct drm_i915_private *dev_priv = dev->dev_private; | 354 | struct drm_i915_private *dev_priv = dev->dev_private; |
355 | struct intel_output *intel_output = to_intel_output(connector); | 355 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
356 | struct intel_dvo_device *dvo = intel_output->dev_priv; | 356 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
357 | uint32_t dvo_reg = dvo->dvo_reg; | 357 | uint32_t dvo_reg = dvo->dvo_reg; |
358 | uint32_t dvo_val = I915_READ(dvo_reg); | 358 | uint32_t dvo_val = I915_READ(dvo_reg); |
359 | struct drm_display_mode *mode = NULL; | 359 | struct drm_display_mode *mode = NULL; |
@@ -383,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
383 | 383 | ||
384 | void intel_dvo_init(struct drm_device *dev) | 384 | void intel_dvo_init(struct drm_device *dev) |
385 | { | 385 | { |
386 | struct intel_output *intel_output; | 386 | struct intel_encoder *intel_encoder; |
387 | struct intel_dvo_device *dvo; | 387 | struct intel_dvo_device *dvo; |
388 | struct i2c_adapter *i2cbus = NULL; | 388 | struct i2c_adapter *i2cbus = NULL; |
389 | int ret = 0; | 389 | int ret = 0; |
390 | int i; | 390 | int i; |
391 | int encoder_type = DRM_MODE_ENCODER_NONE; | 391 | int encoder_type = DRM_MODE_ENCODER_NONE; |
392 | intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); | 392 | intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); |
393 | if (!intel_output) | 393 | if (!intel_encoder) |
394 | return; | 394 | return; |
395 | 395 | ||
396 | /* Set up the DDC bus */ | 396 | /* Set up the DDC bus */ |
397 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 397 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
398 | if (!intel_output->ddc_bus) | 398 | if (!intel_encoder->ddc_bus) |
399 | goto free_intel; | 399 | goto free_intel; |
400 | 400 | ||
401 | /* Now, try to find a controller */ | 401 | /* Now, try to find a controller */ |
402 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 402 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
403 | struct drm_connector *connector = &intel_output->base; | 403 | struct drm_connector *connector = &intel_encoder->base; |
404 | int gpio; | 404 | int gpio; |
405 | 405 | ||
406 | dvo = &intel_dvo_devices[i]; | 406 | dvo = &intel_dvo_devices[i]; |
@@ -435,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev) | |||
435 | if (!ret) | 435 | if (!ret) |
436 | continue; | 436 | continue; |
437 | 437 | ||
438 | intel_output->type = INTEL_OUTPUT_DVO; | 438 | intel_encoder->type = INTEL_OUTPUT_DVO; |
439 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 439 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
440 | switch (dvo->type) { | 440 | switch (dvo->type) { |
441 | case INTEL_DVO_CHIP_TMDS: | 441 | case INTEL_DVO_CHIP_TMDS: |
442 | intel_output->clone_mask = | 442 | intel_encoder->clone_mask = |
443 | (1 << INTEL_DVO_TMDS_CLONE_BIT) | | 443 | (1 << INTEL_DVO_TMDS_CLONE_BIT) | |
444 | (1 << INTEL_ANALOG_CLONE_BIT); | 444 | (1 << INTEL_ANALOG_CLONE_BIT); |
445 | drm_connector_init(dev, connector, | 445 | drm_connector_init(dev, connector, |
@@ -448,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
448 | encoder_type = DRM_MODE_ENCODER_TMDS; | 448 | encoder_type = DRM_MODE_ENCODER_TMDS; |
449 | break; | 449 | break; |
450 | case INTEL_DVO_CHIP_LVDS: | 450 | case INTEL_DVO_CHIP_LVDS: |
451 | intel_output->clone_mask = | 451 | intel_encoder->clone_mask = |
452 | (1 << INTEL_DVO_LVDS_CLONE_BIT); | 452 | (1 << INTEL_DVO_LVDS_CLONE_BIT); |
453 | drm_connector_init(dev, connector, | 453 | drm_connector_init(dev, connector, |
454 | &intel_dvo_connector_funcs, | 454 | &intel_dvo_connector_funcs, |
@@ -463,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev) | |||
463 | connector->interlace_allowed = false; | 463 | connector->interlace_allowed = false; |
464 | connector->doublescan_allowed = false; | 464 | connector->doublescan_allowed = false; |
465 | 465 | ||
466 | intel_output->dev_priv = dvo; | 466 | intel_encoder->dev_priv = dvo; |
467 | intel_output->i2c_bus = i2cbus; | 467 | intel_encoder->i2c_bus = i2cbus; |
468 | 468 | ||
469 | drm_encoder_init(dev, &intel_output->enc, | 469 | drm_encoder_init(dev, &intel_encoder->enc, |
470 | &intel_dvo_enc_funcs, encoder_type); | 470 | &intel_dvo_enc_funcs, encoder_type); |
471 | drm_encoder_helper_add(&intel_output->enc, | 471 | drm_encoder_helper_add(&intel_encoder->enc, |
472 | &intel_dvo_helper_funcs); | 472 | &intel_dvo_helper_funcs); |
473 | 473 | ||
474 | drm_mode_connector_attach_encoder(&intel_output->base, | 474 | drm_mode_connector_attach_encoder(&intel_encoder->base, |
475 | &intel_output->enc); | 475 | &intel_encoder->enc); |
476 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { | 476 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { |
477 | /* For our LVDS chipsets, we should hopefully be able | 477 | /* For our LVDS chipsets, we should hopefully be able |
478 | * to dig the fixed panel mode out of the BIOS data. | 478 | * to dig the fixed panel mode out of the BIOS data. |
@@ -490,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev) | |||
490 | return; | 490 | return; |
491 | } | 491 | } |
492 | 492 | ||
493 | intel_i2c_destroy(intel_output->ddc_bus); | 493 | intel_i2c_destroy(intel_encoder->ddc_bus); |
494 | /* Didn't find a chip, so tear down. */ | 494 | /* Didn't find a chip, so tear down. */ |
495 | if (i2cbus != NULL) | 495 | if (i2cbus != NULL) |
496 | intel_i2c_destroy(i2cbus); | 496 | intel_i2c_destroy(i2cbus); |
497 | free_intel: | 497 | free_intel: |
498 | kfree(intel_output); | 498 | kfree(intel_encoder); |
499 | } | 499 | } |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 69bbef92f130..8a0b3bcdc7b1 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -144,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
144 | ret = -ENOMEM; | 144 | ret = -ENOMEM; |
145 | goto out; | 145 | goto out; |
146 | } | 146 | } |
147 | obj_priv = fbo->driver_private; | 147 | obj_priv = to_intel_bo(fbo); |
148 | 148 | ||
149 | mutex_lock(&dev->struct_mutex); | 149 | mutex_lock(&dev->struct_mutex); |
150 | 150 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1ed02f641258..48cade0cf7b1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -51,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
51 | struct drm_i915_private *dev_priv = dev->dev_private; | 51 | struct drm_i915_private *dev_priv = dev->dev_private; |
52 | struct drm_crtc *crtc = encoder->crtc; | 52 | struct drm_crtc *crtc = encoder->crtc; |
53 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 53 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
54 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 54 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
55 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 55 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
56 | u32 sdvox; | 56 | u32 sdvox; |
57 | 57 | ||
58 | sdvox = SDVO_ENCODING_HDMI | | 58 | sdvox = SDVO_ENCODING_HDMI | |
@@ -74,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
74 | { | 74 | { |
75 | struct drm_device *dev = encoder->dev; | 75 | struct drm_device *dev = encoder->dev; |
76 | struct drm_i915_private *dev_priv = dev->dev_private; | 76 | struct drm_i915_private *dev_priv = dev->dev_private; |
77 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 77 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
78 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 78 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
79 | u32 temp; | 79 | u32 temp; |
80 | 80 | ||
81 | temp = I915_READ(hdmi_priv->sdvox_reg); | 81 | temp = I915_READ(hdmi_priv->sdvox_reg); |
@@ -110,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector) | |||
110 | { | 110 | { |
111 | struct drm_device *dev = connector->dev; | 111 | struct drm_device *dev = connector->dev; |
112 | struct drm_i915_private *dev_priv = dev->dev_private; | 112 | struct drm_i915_private *dev_priv = dev->dev_private; |
113 | struct intel_output *intel_output = to_intel_output(connector); | 113 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
114 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 114 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
115 | 115 | ||
116 | hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); | 116 | hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); |
117 | } | 117 | } |
@@ -120,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector) | |||
120 | { | 120 | { |
121 | struct drm_device *dev = connector->dev; | 121 | struct drm_device *dev = connector->dev; |
122 | struct drm_i915_private *dev_priv = dev->dev_private; | 122 | struct drm_i915_private *dev_priv = dev->dev_private; |
123 | struct intel_output *intel_output = to_intel_output(connector); | 123 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
124 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 124 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
125 | 125 | ||
126 | I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); | 126 | I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); |
127 | POSTING_READ(hdmi_priv->sdvox_reg); | 127 | POSTING_READ(hdmi_priv->sdvox_reg); |
@@ -151,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
151 | static enum drm_connector_status | 151 | static enum drm_connector_status |
152 | intel_hdmi_detect(struct drm_connector *connector) | 152 | intel_hdmi_detect(struct drm_connector *connector) |
153 | { | 153 | { |
154 | struct intel_output *intel_output = to_intel_output(connector); | 154 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
155 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 155 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; |
156 | struct edid *edid = NULL; | 156 | struct edid *edid = NULL; |
157 | enum drm_connector_status status = connector_status_disconnected; | 157 | enum drm_connector_status status = connector_status_disconnected; |
158 | 158 | ||
159 | hdmi_priv->has_hdmi_sink = false; | 159 | hdmi_priv->has_hdmi_sink = false; |
160 | edid = drm_get_edid(&intel_output->base, | 160 | edid = drm_get_edid(&intel_encoder->base, |
161 | intel_output->ddc_bus); | 161 | intel_encoder->ddc_bus); |
162 | 162 | ||
163 | if (edid) { | 163 | if (edid) { |
164 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 164 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
165 | status = connector_status_connected; | 165 | status = connector_status_connected; |
166 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 166 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
167 | } | 167 | } |
168 | intel_output->base.display_info.raw_edid = NULL; | 168 | intel_encoder->base.display_info.raw_edid = NULL; |
169 | kfree(edid); | 169 | kfree(edid); |
170 | } | 170 | } |
171 | 171 | ||
@@ -174,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
174 | 174 | ||
175 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 175 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
176 | { | 176 | { |
177 | struct intel_output *intel_output = to_intel_output(connector); | 177 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
178 | 178 | ||
179 | /* We should parse the EDID data and find out if it's an HDMI sink so | 179 | /* We should parse the EDID data and find out if it's an HDMI sink so |
180 | * we can send audio to it. | 180 | * we can send audio to it. |
181 | */ | 181 | */ |
182 | 182 | ||
183 | return intel_ddc_get_modes(intel_output); | 183 | return intel_ddc_get_modes(intel_encoder); |
184 | } | 184 | } |
185 | 185 | ||
186 | static void intel_hdmi_destroy(struct drm_connector *connector) | 186 | static void intel_hdmi_destroy(struct drm_connector *connector) |
187 | { | 187 | { |
188 | struct intel_output *intel_output = to_intel_output(connector); | 188 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
189 | 189 | ||
190 | if (intel_output->i2c_bus) | 190 | if (intel_encoder->i2c_bus) |
191 | intel_i2c_destroy(intel_output->i2c_bus); | 191 | intel_i2c_destroy(intel_encoder->i2c_bus); |
192 | drm_sysfs_connector_remove(connector); | 192 | drm_sysfs_connector_remove(connector); |
193 | drm_connector_cleanup(connector); | 193 | drm_connector_cleanup(connector); |
194 | kfree(intel_output); | 194 | kfree(intel_encoder); |
195 | } | 195 | } |
196 | 196 | ||
197 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | 197 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
@@ -230,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
230 | { | 230 | { |
231 | struct drm_i915_private *dev_priv = dev->dev_private; | 231 | struct drm_i915_private *dev_priv = dev->dev_private; |
232 | struct drm_connector *connector; | 232 | struct drm_connector *connector; |
233 | struct intel_output *intel_output; | 233 | struct intel_encoder *intel_encoder; |
234 | struct intel_hdmi_priv *hdmi_priv; | 234 | struct intel_hdmi_priv *hdmi_priv; |
235 | 235 | ||
236 | intel_output = kcalloc(sizeof(struct intel_output) + | 236 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + |
237 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 237 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); |
238 | if (!intel_output) | 238 | if (!intel_encoder) |
239 | return; | 239 | return; |
240 | hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1); | 240 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); |
241 | 241 | ||
242 | connector = &intel_output->base; | 242 | connector = &intel_encoder->base; |
243 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 243 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
244 | DRM_MODE_CONNECTOR_HDMIA); | 244 | DRM_MODE_CONNECTOR_HDMIA); |
245 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); | 245 | drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); |
246 | 246 | ||
247 | intel_output->type = INTEL_OUTPUT_HDMI; | 247 | intel_encoder->type = INTEL_OUTPUT_HDMI; |
248 | 248 | ||
249 | connector->interlace_allowed = 0; | 249 | connector->interlace_allowed = 0; |
250 | connector->doublescan_allowed = 0; | 250 | connector->doublescan_allowed = 0; |
251 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 251 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
252 | 252 | ||
253 | /* Set up the DDC bus. */ | 253 | /* Set up the DDC bus. */ |
254 | if (sdvox_reg == SDVOB) { | 254 | if (sdvox_reg == SDVOB) { |
255 | intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); | 255 | intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); |
256 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); | 256 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); |
257 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | 257 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; |
258 | } else if (sdvox_reg == SDVOC) { | 258 | } else if (sdvox_reg == SDVOC) { |
259 | intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); | 259 | intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); |
260 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); | 260 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); |
261 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | 261 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; |
262 | } else if (sdvox_reg == HDMIB) { | 262 | } else if (sdvox_reg == HDMIB) { |
263 | intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); | 263 | intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); |
264 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, | 264 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, |
265 | "HDMIB"); | 265 | "HDMIB"); |
266 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; | 266 | dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; |
267 | } else if (sdvox_reg == HDMIC) { | 267 | } else if (sdvox_reg == HDMIC) { |
268 | intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); | 268 | intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); |
269 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, | 269 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, |
270 | "HDMIC"); | 270 | "HDMIC"); |
271 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; | 271 | dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; |
272 | } else if (sdvox_reg == HDMID) { | 272 | } else if (sdvox_reg == HDMID) { |
273 | intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); | 273 | intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); |
274 | intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, | 274 | intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, |
275 | "HDMID"); | 275 | "HDMID"); |
276 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; | 276 | dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; |
277 | } | 277 | } |
278 | if (!intel_output->ddc_bus) | 278 | if (!intel_encoder->ddc_bus) |
279 | goto err_connector; | 279 | goto err_connector; |
280 | 280 | ||
281 | hdmi_priv->sdvox_reg = sdvox_reg; | 281 | hdmi_priv->sdvox_reg = sdvox_reg; |
282 | intel_output->dev_priv = hdmi_priv; | 282 | intel_encoder->dev_priv = hdmi_priv; |
283 | 283 | ||
284 | drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs, | 284 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, |
285 | DRM_MODE_ENCODER_TMDS); | 285 | DRM_MODE_ENCODER_TMDS); |
286 | drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs); | 286 | drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); |
287 | 287 | ||
288 | drm_mode_connector_attach_encoder(&intel_output->base, | 288 | drm_mode_connector_attach_encoder(&intel_encoder->base, |
289 | &intel_output->enc); | 289 | &intel_encoder->enc); |
290 | drm_sysfs_connector_add(connector); | 290 | drm_sysfs_connector_add(connector); |
291 | 291 | ||
292 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | 292 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written |
@@ -302,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
302 | 302 | ||
303 | err_connector: | 303 | err_connector: |
304 | drm_connector_cleanup(connector); | 304 | drm_connector_cleanup(connector); |
305 | kfree(intel_output); | 305 | kfree(intel_encoder); |
306 | 306 | ||
307 | return; | 307 | return; |
308 | } | 308 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 216e9f52b6e0..b66806a37d37 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -239,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
239 | struct drm_i915_private *dev_priv = dev->dev_private; | 239 | struct drm_i915_private *dev_priv = dev->dev_private; |
240 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 240 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
241 | struct drm_encoder *tmp_encoder; | 241 | struct drm_encoder *tmp_encoder; |
242 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 242 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
243 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | 243 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; |
244 | u32 pfit_control = 0, pfit_pgm_ratios = 0; | 244 | u32 pfit_control = 0, pfit_pgm_ratios = 0; |
245 | int left_border = 0, right_border = 0, top_border = 0; | 245 | int left_border = 0, right_border = 0, top_border = 0; |
246 | int bottom_border = 0; | 246 | int bottom_border = 0; |
@@ -587,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
587 | { | 587 | { |
588 | struct drm_device *dev = encoder->dev; | 588 | struct drm_device *dev = encoder->dev; |
589 | struct drm_i915_private *dev_priv = dev->dev_private; | 589 | struct drm_i915_private *dev_priv = dev->dev_private; |
590 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 590 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
591 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | 591 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; |
592 | 592 | ||
593 | /* | 593 | /* |
594 | * The LVDS pin pair will already have been turned on in the | 594 | * The LVDS pin pair will already have been turned on in the |
@@ -635,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect | |||
635 | static int intel_lvds_get_modes(struct drm_connector *connector) | 635 | static int intel_lvds_get_modes(struct drm_connector *connector) |
636 | { | 636 | { |
637 | struct drm_device *dev = connector->dev; | 637 | struct drm_device *dev = connector->dev; |
638 | struct intel_output *intel_output = to_intel_output(connector); | 638 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
639 | struct drm_i915_private *dev_priv = dev->dev_private; | 639 | struct drm_i915_private *dev_priv = dev->dev_private; |
640 | int ret = 0; | 640 | int ret = 0; |
641 | 641 | ||
642 | ret = intel_ddc_get_modes(intel_output); | 642 | if (dev_priv->lvds_edid_good) { |
643 | ret = intel_ddc_get_modes(intel_encoder); | ||
643 | 644 | ||
644 | if (ret) | 645 | if (ret) |
645 | return ret; | 646 | return ret; |
647 | } | ||
646 | 648 | ||
647 | /* Didn't get an EDID, so | 649 | /* Didn't get an EDID, so |
648 | * Set wide sync ranges so we get all modes | 650 | * Set wide sync ranges so we get all modes |
@@ -715,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
715 | static void intel_lvds_destroy(struct drm_connector *connector) | 717 | static void intel_lvds_destroy(struct drm_connector *connector) |
716 | { | 718 | { |
717 | struct drm_device *dev = connector->dev; | 719 | struct drm_device *dev = connector->dev; |
718 | struct intel_output *intel_output = to_intel_output(connector); | 720 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
719 | struct drm_i915_private *dev_priv = dev->dev_private; | 721 | struct drm_i915_private *dev_priv = dev->dev_private; |
720 | 722 | ||
721 | if (intel_output->ddc_bus) | 723 | if (intel_encoder->ddc_bus) |
722 | intel_i2c_destroy(intel_output->ddc_bus); | 724 | intel_i2c_destroy(intel_encoder->ddc_bus); |
723 | if (dev_priv->lid_notifier.notifier_call) | 725 | if (dev_priv->lid_notifier.notifier_call) |
724 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); | 726 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); |
725 | drm_sysfs_connector_remove(connector); | 727 | drm_sysfs_connector_remove(connector); |
@@ -732,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
732 | uint64_t value) | 734 | uint64_t value) |
733 | { | 735 | { |
734 | struct drm_device *dev = connector->dev; | 736 | struct drm_device *dev = connector->dev; |
735 | struct intel_output *intel_output = | 737 | struct intel_encoder *intel_encoder = |
736 | to_intel_output(connector); | 738 | to_intel_encoder(connector); |
737 | 739 | ||
738 | if (property == dev->mode_config.scaling_mode_property && | 740 | if (property == dev->mode_config.scaling_mode_property && |
739 | connector->encoder) { | 741 | connector->encoder) { |
740 | struct drm_crtc *crtc = connector->encoder->crtc; | 742 | struct drm_crtc *crtc = connector->encoder->crtc; |
741 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | 743 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; |
742 | if (value == DRM_MODE_SCALE_NONE) { | 744 | if (value == DRM_MODE_SCALE_NONE) { |
743 | DRM_DEBUG_KMS("no scaling not supported\n"); | 745 | DRM_DEBUG_KMS("no scaling not supported\n"); |
744 | return 0; | 746 | return 0; |
@@ -858,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
858 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 860 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
859 | }, | 861 | }, |
860 | }, | 862 | }, |
863 | { | ||
864 | .callback = intel_no_lvds_dmi_callback, | ||
865 | .ident = "Clientron U800", | ||
866 | .matches = { | ||
867 | DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), | ||
868 | DMI_MATCH(DMI_PRODUCT_NAME, "U800"), | ||
869 | }, | ||
870 | }, | ||
861 | 871 | ||
862 | { } /* terminating entry */ | 872 | { } /* terminating entry */ |
863 | }; | 873 | }; |
@@ -968,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) | |||
968 | void intel_lvds_init(struct drm_device *dev) | 978 | void intel_lvds_init(struct drm_device *dev) |
969 | { | 979 | { |
970 | struct drm_i915_private *dev_priv = dev->dev_private; | 980 | struct drm_i915_private *dev_priv = dev->dev_private; |
971 | struct intel_output *intel_output; | 981 | struct intel_encoder *intel_encoder; |
972 | struct drm_connector *connector; | 982 | struct drm_connector *connector; |
973 | struct drm_encoder *encoder; | 983 | struct drm_encoder *encoder; |
974 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 984 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
@@ -996,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev) | |||
996 | gpio = PCH_GPIOC; | 1006 | gpio = PCH_GPIOC; |
997 | } | 1007 | } |
998 | 1008 | ||
999 | intel_output = kzalloc(sizeof(struct intel_output) + | 1009 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + |
1000 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | 1010 | sizeof(struct intel_lvds_priv), GFP_KERNEL); |
1001 | if (!intel_output) { | 1011 | if (!intel_encoder) { |
1002 | return; | 1012 | return; |
1003 | } | 1013 | } |
1004 | 1014 | ||
1005 | connector = &intel_output->base; | 1015 | connector = &intel_encoder->base; |
1006 | encoder = &intel_output->enc; | 1016 | encoder = &intel_encoder->enc; |
1007 | drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, | 1017 | drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs, |
1008 | DRM_MODE_CONNECTOR_LVDS); | 1018 | DRM_MODE_CONNECTOR_LVDS); |
1009 | 1019 | ||
1010 | drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, | 1020 | drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, |
1011 | DRM_MODE_ENCODER_LVDS); | 1021 | DRM_MODE_ENCODER_LVDS); |
1012 | 1022 | ||
1013 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1023 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); |
1014 | intel_output->type = INTEL_OUTPUT_LVDS; | 1024 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
1015 | 1025 | ||
1016 | intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); | 1026 | intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); |
1017 | intel_output->crtc_mask = (1 << 1); | 1027 | intel_encoder->crtc_mask = (1 << 1); |
1018 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); | 1028 | drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); |
1019 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); | 1029 | drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); |
1020 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 1030 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
1021 | connector->interlace_allowed = false; | 1031 | connector->interlace_allowed = false; |
1022 | connector->doublescan_allowed = false; | 1032 | connector->doublescan_allowed = false; |
1023 | 1033 | ||
1024 | lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); | 1034 | lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); |
1025 | intel_output->dev_priv = lvds_priv; | 1035 | intel_encoder->dev_priv = lvds_priv; |
1026 | /* create the scaling mode property */ | 1036 | /* create the scaling mode property */ |
1027 | drm_mode_create_scaling_mode_property(dev); | 1037 | drm_mode_create_scaling_mode_property(dev); |
1028 | /* | 1038 | /* |
1029 | * the initial panel fitting mode will be FULL_SCREEN. | 1039 | * the initial panel fitting mode will be FULL_SCREEN. |
1030 | */ | 1040 | */ |
1031 | 1041 | ||
1032 | drm_connector_attach_property(&intel_output->base, | 1042 | drm_connector_attach_property(&intel_encoder->base, |
1033 | dev->mode_config.scaling_mode_property, | 1043 | dev->mode_config.scaling_mode_property, |
1034 | DRM_MODE_SCALE_FULLSCREEN); | 1044 | DRM_MODE_SCALE_FULLSCREEN); |
1035 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; | 1045 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; |
@@ -1044,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
1044 | */ | 1054 | */ |
1045 | 1055 | ||
1046 | /* Set up the DDC bus. */ | 1056 | /* Set up the DDC bus. */ |
1047 | intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); | 1057 | intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); |
1048 | if (!intel_output->ddc_bus) { | 1058 | if (!intel_encoder->ddc_bus) { |
1049 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " | 1059 | dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " |
1050 | "failed.\n"); | 1060 | "failed.\n"); |
1051 | goto failed; | 1061 | goto failed; |
@@ -1055,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev) | |||
1055 | * Attempt to get the fixed panel mode from DDC. Assume that the | 1065 | * Attempt to get the fixed panel mode from DDC. Assume that the |
1056 | * preferred mode is the right one. | 1066 | * preferred mode is the right one. |
1057 | */ | 1067 | */ |
1058 | intel_ddc_get_modes(intel_output); | 1068 | dev_priv->lvds_edid_good = true; |
1069 | |||
1070 | if (!intel_ddc_get_modes(intel_encoder)) | ||
1071 | dev_priv->lvds_edid_good = false; | ||
1059 | 1072 | ||
1060 | list_for_each_entry(scan, &connector->probed_modes, head) { | 1073 | list_for_each_entry(scan, &connector->probed_modes, head) { |
1061 | mutex_lock(&dev->mode_config.mutex); | 1074 | mutex_lock(&dev->mode_config.mutex); |
@@ -1133,9 +1146,9 @@ out: | |||
1133 | 1146 | ||
1134 | failed: | 1147 | failed: |
1135 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); | 1148 | DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); |
1136 | if (intel_output->ddc_bus) | 1149 | if (intel_encoder->ddc_bus) |
1137 | intel_i2c_destroy(intel_output->ddc_bus); | 1150 | intel_i2c_destroy(intel_encoder->ddc_bus); |
1138 | drm_connector_cleanup(connector); | 1151 | drm_connector_cleanup(connector); |
1139 | drm_encoder_cleanup(encoder); | 1152 | drm_encoder_cleanup(encoder); |
1140 | kfree(intel_output); | 1153 | kfree(intel_encoder); |
1141 | } | 1154 | } |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 89d303d1d3fb..8e5c83b2d120 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -34,7 +34,7 @@ | |||
34 | * intel_ddc_probe | 34 | * intel_ddc_probe |
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | bool intel_ddc_probe(struct intel_output *intel_output) | 37 | bool intel_ddc_probe(struct intel_encoder *intel_encoder) |
38 | { | 38 | { |
39 | u8 out_buf[] = { 0x0, 0x0}; | 39 | u8 out_buf[] = { 0x0, 0x0}; |
40 | u8 buf[2]; | 40 | u8 buf[2]; |
@@ -54,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output) | |||
54 | } | 54 | } |
55 | }; | 55 | }; |
56 | 56 | ||
57 | intel_i2c_quirk_set(intel_output->base.dev, true); | 57 | intel_i2c_quirk_set(intel_encoder->base.dev, true); |
58 | ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); | 58 | ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); |
59 | intel_i2c_quirk_set(intel_output->base.dev, false); | 59 | intel_i2c_quirk_set(intel_encoder->base.dev, false); |
60 | if (ret == 2) | 60 | if (ret == 2) |
61 | return true; | 61 | return true; |
62 | 62 | ||
@@ -69,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output) | |||
69 | * | 69 | * |
70 | * Fetch the EDID information from @connector using the DDC bus. | 70 | * Fetch the EDID information from @connector using the DDC bus. |
71 | */ | 71 | */ |
72 | int intel_ddc_get_modes(struct intel_output *intel_output) | 72 | int intel_ddc_get_modes(struct intel_encoder *intel_encoder) |
73 | { | 73 | { |
74 | struct edid *edid; | 74 | struct edid *edid; |
75 | int ret = 0; | 75 | int ret = 0; |
76 | 76 | ||
77 | intel_i2c_quirk_set(intel_output->base.dev, true); | 77 | intel_i2c_quirk_set(intel_encoder->base.dev, true); |
78 | edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); | 78 | edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus); |
79 | intel_i2c_quirk_set(intel_output->base.dev, false); | 79 | intel_i2c_quirk_set(intel_encoder->base.dev, false); |
80 | if (edid) { | 80 | if (edid) { |
81 | drm_mode_connector_update_edid_property(&intel_output->base, | 81 | drm_mode_connector_update_edid_property(&intel_encoder->base, |
82 | edid); | 82 | edid); |
83 | ret = drm_add_edid_modes(&intel_output->base, edid); | 83 | ret = drm_add_edid_modes(&intel_encoder->base, edid); |
84 | intel_output->base.display_info.raw_edid = NULL; | 84 | intel_encoder->base.display_info.raw_edid = NULL; |
85 | kfree(edid); | 85 | kfree(edid); |
86 | } | 86 | } |
87 | 87 | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 60595fc26fdd..6d524a1fc271 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
724 | int ret, tmp_width; | 724 | int ret, tmp_width; |
725 | struct overlay_registers *regs; | 725 | struct overlay_registers *regs; |
726 | bool scale_changed = false; | 726 | bool scale_changed = false; |
727 | struct drm_i915_gem_object *bo_priv = new_bo->driver_private; | 727 | struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); |
728 | struct drm_device *dev = overlay->dev; | 728 | struct drm_device *dev = overlay->dev; |
729 | 729 | ||
730 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); | 730 | BUG_ON(!mutex_is_locked(&dev->struct_mutex)); |
@@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
809 | intel_overlay_continue(overlay, scale_changed); | 809 | intel_overlay_continue(overlay, scale_changed); |
810 | 810 | ||
811 | overlay->old_vid_bo = overlay->vid_bo; | 811 | overlay->old_vid_bo = overlay->vid_bo; |
812 | overlay->vid_bo = new_bo->driver_private; | 812 | overlay->vid_bo = to_intel_bo(new_bo); |
813 | 813 | ||
814 | return 0; | 814 | return 0; |
815 | 815 | ||
@@ -1344,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1344 | reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE); | 1344 | reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE); |
1345 | if (!reg_bo) | 1345 | if (!reg_bo) |
1346 | goto out_free; | 1346 | goto out_free; |
1347 | overlay->reg_bo = reg_bo->driver_private; | 1347 | overlay->reg_bo = to_intel_bo(reg_bo); |
1348 | 1348 | ||
1349 | if (OVERLAY_NONPHYSICAL(dev)) { | 1349 | if (OVERLAY_NONPHYSICAL(dev)) { |
1350 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); | 1350 | ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 26e13a0bf30b..87d953664cb0 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -54,7 +54,7 @@ struct intel_sdvo_priv { | |||
54 | u8 slave_addr; | 54 | u8 slave_addr; |
55 | 55 | ||
56 | /* Register for the SDVO device: SDVOB or SDVOC */ | 56 | /* Register for the SDVO device: SDVOB or SDVOC */ |
57 | int output_device; | 57 | int sdvo_reg; |
58 | 58 | ||
59 | /* Active outputs controlled by this SDVO output */ | 59 | /* Active outputs controlled by this SDVO output */ |
60 | uint16_t controlled_output; | 60 | uint16_t controlled_output; |
@@ -124,7 +124,7 @@ struct intel_sdvo_priv { | |||
124 | */ | 124 | */ |
125 | struct intel_sdvo_encode encode; | 125 | struct intel_sdvo_encode encode; |
126 | 126 | ||
127 | /* DDC bus used by this SDVO output */ | 127 | /* DDC bus used by this SDVO encoder */ |
128 | uint8_t ddc_bus; | 128 | uint8_t ddc_bus; |
129 | 129 | ||
130 | /* Mac mini hack -- use the same DDC as the analog connector */ | 130 | /* Mac mini hack -- use the same DDC as the analog connector */ |
@@ -162,22 +162,22 @@ struct intel_sdvo_priv { | |||
162 | }; | 162 | }; |
163 | 163 | ||
164 | static bool | 164 | static bool |
165 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); | 165 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); |
166 | 166 | ||
167 | /** | 167 | /** |
168 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 168 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
169 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 169 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
170 | * comments in the BIOS). | 170 | * comments in the BIOS). |
171 | */ | 171 | */ |
172 | static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) | 172 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) |
173 | { | 173 | { |
174 | struct drm_device *dev = intel_output->base.dev; | 174 | struct drm_device *dev = intel_encoder->base.dev; |
175 | struct drm_i915_private *dev_priv = dev->dev_private; | 175 | struct drm_i915_private *dev_priv = dev->dev_private; |
176 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 176 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
177 | u32 bval = val, cval = val; | 177 | u32 bval = val, cval = val; |
178 | int i; | 178 | int i; |
179 | 179 | ||
180 | if (sdvo_priv->output_device == SDVOB) { | 180 | if (sdvo_priv->sdvo_reg == SDVOB) { |
181 | cval = I915_READ(SDVOC); | 181 | cval = I915_READ(SDVOC); |
182 | } else { | 182 | } else { |
183 | bval = I915_READ(SDVOB); | 183 | bval = I915_READ(SDVOB); |
@@ -196,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | 198 | ||
199 | static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | 199 | static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, |
200 | u8 *ch) | 200 | u8 *ch) |
201 | { | 201 | { |
202 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 202 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
203 | u8 out_buf[2]; | 203 | u8 out_buf[2]; |
204 | u8 buf[2]; | 204 | u8 buf[2]; |
205 | int ret; | 205 | int ret; |
@@ -222,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
222 | out_buf[0] = addr; | 222 | out_buf[0] = addr; |
223 | out_buf[1] = 0; | 223 | out_buf[1] = 0; |
224 | 224 | ||
225 | if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) | 225 | if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) |
226 | { | 226 | { |
227 | *ch = buf[0]; | 227 | *ch = buf[0]; |
228 | return true; | 228 | return true; |
@@ -232,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
232 | return false; | 232 | return false; |
233 | } | 233 | } |
234 | 234 | ||
235 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | 235 | static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, |
236 | u8 ch) | 236 | u8 ch) |
237 | { | 237 | { |
238 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 238 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
239 | u8 out_buf[2]; | 239 | u8 out_buf[2]; |
240 | struct i2c_msg msgs[] = { | 240 | struct i2c_msg msgs[] = { |
241 | { | 241 | { |
@@ -249,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | |||
249 | out_buf[0] = addr; | 249 | out_buf[0] = addr; |
250 | out_buf[1] = ch; | 250 | out_buf[1] = ch; |
251 | 251 | ||
252 | if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) | 252 | if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) |
253 | { | 253 | { |
254 | return true; | 254 | return true; |
255 | } | 255 | } |
@@ -353,13 +353,13 @@ static const struct _sdvo_cmd_name { | |||
353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), | 353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), |
354 | }; | 354 | }; |
355 | 355 | ||
356 | #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") | 356 | #define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") |
357 | #define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) | 357 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) |
358 | 358 | ||
359 | static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, | 359 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, |
360 | void *args, int args_len) | 360 | void *args, int args_len) |
361 | { | 361 | { |
362 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 362 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
363 | int i; | 363 | int i; |
364 | 364 | ||
365 | DRM_DEBUG_KMS("%s: W: %02X ", | 365 | DRM_DEBUG_KMS("%s: W: %02X ", |
@@ -379,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, | |||
379 | DRM_LOG_KMS("\n"); | 379 | DRM_LOG_KMS("\n"); |
380 | } | 380 | } |
381 | 381 | ||
382 | static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd, | 382 | static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, |
383 | void *args, int args_len) | 383 | void *args, int args_len) |
384 | { | 384 | { |
385 | int i; | 385 | int i; |
386 | 386 | ||
387 | intel_sdvo_debug_write(intel_output, cmd, args, args_len); | 387 | intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); |
388 | 388 | ||
389 | for (i = 0; i < args_len; i++) { | 389 | for (i = 0; i < args_len; i++) { |
390 | intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, | 390 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, |
391 | ((u8*)args)[i]); | 391 | ((u8*)args)[i]); |
392 | } | 392 | } |
393 | 393 | ||
394 | intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd); | 394 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); |
395 | } | 395 | } |
396 | 396 | ||
397 | static const char *cmd_status_names[] = { | 397 | static const char *cmd_status_names[] = { |
@@ -404,11 +404,11 @@ static const char *cmd_status_names[] = { | |||
404 | "Scaling not supported" | 404 | "Scaling not supported" |
405 | }; | 405 | }; |
406 | 406 | ||
407 | static void intel_sdvo_debug_response(struct intel_output *intel_output, | 407 | static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, |
408 | void *response, int response_len, | 408 | void *response, int response_len, |
409 | u8 status) | 409 | u8 status) |
410 | { | 410 | { |
411 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 411 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
412 | int i; | 412 | int i; |
413 | 413 | ||
414 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); | 414 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); |
@@ -423,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, | |||
423 | DRM_LOG_KMS("\n"); | 423 | DRM_LOG_KMS("\n"); |
424 | } | 424 | } |
425 | 425 | ||
426 | static u8 intel_sdvo_read_response(struct intel_output *intel_output, | 426 | static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, |
427 | void *response, int response_len) | 427 | void *response, int response_len) |
428 | { | 428 | { |
429 | int i; | 429 | int i; |
@@ -433,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output, | |||
433 | while (retry--) { | 433 | while (retry--) { |
434 | /* Read the command response */ | 434 | /* Read the command response */ |
435 | for (i = 0; i < response_len; i++) { | 435 | for (i = 0; i < response_len; i++) { |
436 | intel_sdvo_read_byte(intel_output, | 436 | intel_sdvo_read_byte(intel_encoder, |
437 | SDVO_I2C_RETURN_0 + i, | 437 | SDVO_I2C_RETURN_0 + i, |
438 | &((u8 *)response)[i]); | 438 | &((u8 *)response)[i]); |
439 | } | 439 | } |
440 | 440 | ||
441 | /* read the return status */ | 441 | /* read the return status */ |
442 | intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, | 442 | intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, |
443 | &status); | 443 | &status); |
444 | 444 | ||
445 | intel_sdvo_debug_response(intel_output, response, response_len, | 445 | intel_sdvo_debug_response(intel_encoder, response, response_len, |
446 | status); | 446 | status); |
447 | if (status != SDVO_CMD_STATUS_PENDING) | 447 | if (status != SDVO_CMD_STATUS_PENDING) |
448 | return status; | 448 | return status; |
@@ -470,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
470 | * another I2C transaction after issuing the DDC bus switch, it will be | 470 | * another I2C transaction after issuing the DDC bus switch, it will be |
471 | * switched to the internal SDVO register. | 471 | * switched to the internal SDVO register. |
472 | */ | 472 | */ |
473 | static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | 473 | static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, |
474 | u8 target) | 474 | u8 target) |
475 | { | 475 | { |
476 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 476 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
477 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 477 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
478 | struct i2c_msg msgs[] = { | 478 | struct i2c_msg msgs[] = { |
479 | { | 479 | { |
@@ -497,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | |||
497 | }, | 497 | }, |
498 | }; | 498 | }; |
499 | 499 | ||
500 | intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 500 | intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
501 | &target, 1); | 501 | &target, 1); |
502 | /* write the DDC switch command argument */ | 502 | /* write the DDC switch command argument */ |
503 | intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); | 503 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); |
504 | 504 | ||
505 | out_buf[0] = SDVO_I2C_OPCODE; | 505 | out_buf[0] = SDVO_I2C_OPCODE; |
506 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 506 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
@@ -509,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | |||
509 | ret_value[0] = 0; | 509 | ret_value[0] = 0; |
510 | ret_value[1] = 0; | 510 | ret_value[1] = 0; |
511 | 511 | ||
512 | ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); | 512 | ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); |
513 | if (ret != 3) { | 513 | if (ret != 3) { |
514 | /* failure in I2C transfer */ | 514 | /* failure in I2C transfer */ |
515 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 515 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
@@ -523,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | |||
523 | return; | 523 | return; |
524 | } | 524 | } |
525 | 525 | ||
526 | static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) | 526 | static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) |
527 | { | 527 | { |
528 | struct intel_sdvo_set_target_input_args targets = {0}; | 528 | struct intel_sdvo_set_target_input_args targets = {0}; |
529 | u8 status; | 529 | u8 status; |
@@ -534,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool | |||
534 | if (target_1) | 534 | if (target_1) |
535 | targets.target_1 = 1; | 535 | targets.target_1 = 1; |
536 | 536 | ||
537 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets, | 537 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, |
538 | sizeof(targets)); | 538 | sizeof(targets)); |
539 | 539 | ||
540 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 540 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
541 | 541 | ||
542 | return (status == SDVO_CMD_STATUS_SUCCESS); | 542 | return (status == SDVO_CMD_STATUS_SUCCESS); |
543 | } | 543 | } |
@@ -548,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool | |||
548 | * This function is making an assumption about the layout of the response, | 548 | * This function is making an assumption about the layout of the response, |
549 | * which should be checked against the docs. | 549 | * which should be checked against the docs. |
550 | */ | 550 | */ |
551 | static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2) | 551 | static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) |
552 | { | 552 | { |
553 | struct intel_sdvo_get_trained_inputs_response response; | 553 | struct intel_sdvo_get_trained_inputs_response response; |
554 | u8 status; | 554 | u8 status; |
555 | 555 | ||
556 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 556 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); |
557 | status = intel_sdvo_read_response(intel_output, &response, sizeof(response)); | 557 | status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); |
558 | if (status != SDVO_CMD_STATUS_SUCCESS) | 558 | if (status != SDVO_CMD_STATUS_SUCCESS) |
559 | return false; | 559 | return false; |
560 | 560 | ||
@@ -563,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo | |||
563 | return true; | 563 | return true; |
564 | } | 564 | } |
565 | 565 | ||
566 | static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output, | 566 | static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder, |
567 | u16 *outputs) | 567 | u16 *outputs) |
568 | { | 568 | { |
569 | u8 status; | 569 | u8 status; |
570 | 570 | ||
571 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); | 571 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); |
572 | status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs)); | 572 | status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs)); |
573 | 573 | ||
574 | return (status == SDVO_CMD_STATUS_SUCCESS); | 574 | return (status == SDVO_CMD_STATUS_SUCCESS); |
575 | } | 575 | } |
576 | 576 | ||
577 | static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output, | 577 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, |
578 | u16 outputs) | 578 | u16 outputs) |
579 | { | 579 | { |
580 | u8 status; | 580 | u8 status; |
581 | 581 | ||
582 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 582 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, |
583 | sizeof(outputs)); | 583 | sizeof(outputs)); |
584 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 584 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
585 | return (status == SDVO_CMD_STATUS_SUCCESS); | 585 | return (status == SDVO_CMD_STATUS_SUCCESS); |
586 | } | 586 | } |
587 | 587 | ||
588 | static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output, | 588 | static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, |
589 | int mode) | 589 | int mode) |
590 | { | 590 | { |
591 | u8 status, state = SDVO_ENCODER_STATE_ON; | 591 | u8 status, state = SDVO_ENCODER_STATE_ON; |
@@ -605,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output | |||
605 | break; | 605 | break; |
606 | } | 606 | } |
607 | 607 | ||
608 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 608 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, |
609 | sizeof(state)); | 609 | sizeof(state)); |
610 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 610 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
611 | 611 | ||
612 | return (status == SDVO_CMD_STATUS_SUCCESS); | 612 | return (status == SDVO_CMD_STATUS_SUCCESS); |
613 | } | 613 | } |
614 | 614 | ||
615 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output, | 615 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, |
616 | int *clock_min, | 616 | int *clock_min, |
617 | int *clock_max) | 617 | int *clock_max) |
618 | { | 618 | { |
619 | struct intel_sdvo_pixel_clock_range clocks; | 619 | struct intel_sdvo_pixel_clock_range clocks; |
620 | u8 status; | 620 | u8 status; |
621 | 621 | ||
622 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | 622 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, |
623 | NULL, 0); | 623 | NULL, 0); |
624 | 624 | ||
625 | status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks)); | 625 | status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); |
626 | 626 | ||
627 | if (status != SDVO_CMD_STATUS_SUCCESS) | 627 | if (status != SDVO_CMD_STATUS_SUCCESS) |
628 | return false; | 628 | return false; |
@@ -634,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou | |||
634 | return true; | 634 | return true; |
635 | } | 635 | } |
636 | 636 | ||
637 | static bool intel_sdvo_set_target_output(struct intel_output *intel_output, | 637 | static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, |
638 | u16 outputs) | 638 | u16 outputs) |
639 | { | 639 | { |
640 | u8 status; | 640 | u8 status; |
641 | 641 | ||
642 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 642 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, |
643 | sizeof(outputs)); | 643 | sizeof(outputs)); |
644 | 644 | ||
645 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 645 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
646 | return (status == SDVO_CMD_STATUS_SUCCESS); | 646 | return (status == SDVO_CMD_STATUS_SUCCESS); |
647 | } | 647 | } |
648 | 648 | ||
649 | static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, | 649 | static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd, |
650 | struct intel_sdvo_dtd *dtd) | 650 | struct intel_sdvo_dtd *dtd) |
651 | { | 651 | { |
652 | u8 status; | 652 | u8 status; |
653 | 653 | ||
654 | intel_sdvo_write_cmd(intel_output, cmd, NULL, 0); | 654 | intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); |
655 | status = intel_sdvo_read_response(intel_output, &dtd->part1, | 655 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, |
656 | sizeof(dtd->part1)); | 656 | sizeof(dtd->part1)); |
657 | if (status != SDVO_CMD_STATUS_SUCCESS) | 657 | if (status != SDVO_CMD_STATUS_SUCCESS) |
658 | return false; | 658 | return false; |
659 | 659 | ||
660 | intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0); | 660 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); |
661 | status = intel_sdvo_read_response(intel_output, &dtd->part2, | 661 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, |
662 | sizeof(dtd->part2)); | 662 | sizeof(dtd->part2)); |
663 | if (status != SDVO_CMD_STATUS_SUCCESS) | 663 | if (status != SDVO_CMD_STATUS_SUCCESS) |
664 | return false; | 664 | return false; |
@@ -666,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, | |||
666 | return true; | 666 | return true; |
667 | } | 667 | } |
668 | 668 | ||
669 | static bool intel_sdvo_get_input_timing(struct intel_output *intel_output, | 669 | static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder, |
670 | struct intel_sdvo_dtd *dtd) | 670 | struct intel_sdvo_dtd *dtd) |
671 | { | 671 | { |
672 | return intel_sdvo_get_timing(intel_output, | 672 | return intel_sdvo_get_timing(intel_encoder, |
673 | SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); | 673 | SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); |
674 | } | 674 | } |
675 | 675 | ||
676 | static bool intel_sdvo_get_output_timing(struct intel_output *intel_output, | 676 | static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder, |
677 | struct intel_sdvo_dtd *dtd) | 677 | struct intel_sdvo_dtd *dtd) |
678 | { | 678 | { |
679 | return intel_sdvo_get_timing(intel_output, | 679 | return intel_sdvo_get_timing(intel_encoder, |
680 | SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); | 680 | SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); |
681 | } | 681 | } |
682 | 682 | ||
683 | static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd, | 683 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, |
684 | struct intel_sdvo_dtd *dtd) | 684 | struct intel_sdvo_dtd *dtd) |
685 | { | 685 | { |
686 | u8 status; | 686 | u8 status; |
687 | 687 | ||
688 | intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1)); | 688 | intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); |
689 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 689 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
690 | if (status != SDVO_CMD_STATUS_SUCCESS) | 690 | if (status != SDVO_CMD_STATUS_SUCCESS) |
691 | return false; | 691 | return false; |
692 | 692 | ||
693 | intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | 693 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); |
694 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 694 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
695 | if (status != SDVO_CMD_STATUS_SUCCESS) | 695 | if (status != SDVO_CMD_STATUS_SUCCESS) |
696 | return false; | 696 | return false; |
697 | 697 | ||
698 | return true; | 698 | return true; |
699 | } | 699 | } |
700 | 700 | ||
701 | static bool intel_sdvo_set_input_timing(struct intel_output *intel_output, | 701 | static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, |
702 | struct intel_sdvo_dtd *dtd) | 702 | struct intel_sdvo_dtd *dtd) |
703 | { | 703 | { |
704 | return intel_sdvo_set_timing(intel_output, | 704 | return intel_sdvo_set_timing(intel_encoder, |
705 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); | 705 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); |
706 | } | 706 | } |
707 | 707 | ||
708 | static bool intel_sdvo_set_output_timing(struct intel_output *intel_output, | 708 | static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, |
709 | struct intel_sdvo_dtd *dtd) | 709 | struct intel_sdvo_dtd *dtd) |
710 | { | 710 | { |
711 | return intel_sdvo_set_timing(intel_output, | 711 | return intel_sdvo_set_timing(intel_encoder, |
712 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); | 712 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
713 | } | 713 | } |
714 | 714 | ||
715 | static bool | 715 | static bool |
716 | intel_sdvo_create_preferred_input_timing(struct intel_output *output, | 716 | intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, |
717 | uint16_t clock, | 717 | uint16_t clock, |
718 | uint16_t width, | 718 | uint16_t width, |
719 | uint16_t height) | 719 | uint16_t height) |
720 | { | 720 | { |
721 | struct intel_sdvo_preferred_input_timing_args args; | 721 | struct intel_sdvo_preferred_input_timing_args args; |
722 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 722 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
723 | uint8_t status; | 723 | uint8_t status; |
724 | 724 | ||
725 | memset(&args, 0, sizeof(args)); | 725 | memset(&args, 0, sizeof(args)); |
@@ -733,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
733 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | 733 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) |
734 | args.scaled = 1; | 734 | args.scaled = 1; |
735 | 735 | ||
736 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 736 | intel_sdvo_write_cmd(intel_encoder, |
737 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | ||
737 | &args, sizeof(args)); | 738 | &args, sizeof(args)); |
738 | status = intel_sdvo_read_response(output, NULL, 0); | 739 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
739 | if (status != SDVO_CMD_STATUS_SUCCESS) | 740 | if (status != SDVO_CMD_STATUS_SUCCESS) |
740 | return false; | 741 | return false; |
741 | 742 | ||
742 | return true; | 743 | return true; |
743 | } | 744 | } |
744 | 745 | ||
745 | static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, | 746 | static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, |
746 | struct intel_sdvo_dtd *dtd) | 747 | struct intel_sdvo_dtd *dtd) |
747 | { | 748 | { |
748 | bool status; | 749 | bool status; |
749 | 750 | ||
750 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 751 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
751 | NULL, 0); | 752 | NULL, 0); |
752 | 753 | ||
753 | status = intel_sdvo_read_response(output, &dtd->part1, | 754 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, |
754 | sizeof(dtd->part1)); | 755 | sizeof(dtd->part1)); |
755 | if (status != SDVO_CMD_STATUS_SUCCESS) | 756 | if (status != SDVO_CMD_STATUS_SUCCESS) |
756 | return false; | 757 | return false; |
757 | 758 | ||
758 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | 759 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
759 | NULL, 0); | 760 | NULL, 0); |
760 | 761 | ||
761 | status = intel_sdvo_read_response(output, &dtd->part2, | 762 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, |
762 | sizeof(dtd->part2)); | 763 | sizeof(dtd->part2)); |
763 | if (status != SDVO_CMD_STATUS_SUCCESS) | 764 | if (status != SDVO_CMD_STATUS_SUCCESS) |
764 | return false; | 765 | return false; |
@@ -766,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, | |||
766 | return false; | 767 | return false; |
767 | } | 768 | } |
768 | 769 | ||
769 | static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) | 770 | static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder) |
770 | { | 771 | { |
771 | u8 response, status; | 772 | u8 response, status; |
772 | 773 | ||
773 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); | 774 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); |
774 | status = intel_sdvo_read_response(intel_output, &response, 1); | 775 | status = intel_sdvo_read_response(intel_encoder, &response, 1); |
775 | 776 | ||
776 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 777 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
777 | DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); | 778 | DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); |
@@ -783,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) | |||
783 | return response; | 784 | return response; |
784 | } | 785 | } |
785 | 786 | ||
786 | static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val) | 787 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) |
787 | { | 788 | { |
788 | u8 status; | 789 | u8 status; |
789 | 790 | ||
790 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | 791 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
791 | status = intel_sdvo_read_response(intel_output, NULL, 0); | 792 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
792 | if (status != SDVO_CMD_STATUS_SUCCESS) | 793 | if (status != SDVO_CMD_STATUS_SUCCESS) |
793 | return false; | 794 | return false; |
794 | 795 | ||
@@ -877,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
877 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 878 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
878 | } | 879 | } |
879 | 880 | ||
880 | static bool intel_sdvo_get_supp_encode(struct intel_output *output, | 881 | static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, |
881 | struct intel_sdvo_encode *encode) | 882 | struct intel_sdvo_encode *encode) |
882 | { | 883 | { |
883 | uint8_t status; | 884 | uint8_t status; |
884 | 885 | ||
885 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 886 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); |
886 | status = intel_sdvo_read_response(output, encode, sizeof(*encode)); | 887 | status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); |
887 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | 888 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ |
888 | memset(encode, 0, sizeof(*encode)); | 889 | memset(encode, 0, sizeof(*encode)); |
889 | return false; | 890 | return false; |
@@ -892,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output, | |||
892 | return true; | 893 | return true; |
893 | } | 894 | } |
894 | 895 | ||
895 | static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) | 896 | static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, |
897 | uint8_t mode) | ||
896 | { | 898 | { |
897 | uint8_t status; | 899 | uint8_t status; |
898 | 900 | ||
899 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); | 901 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); |
900 | status = intel_sdvo_read_response(output, NULL, 0); | 902 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
901 | 903 | ||
902 | return (status == SDVO_CMD_STATUS_SUCCESS); | 904 | return (status == SDVO_CMD_STATUS_SUCCESS); |
903 | } | 905 | } |
904 | 906 | ||
905 | static bool intel_sdvo_set_colorimetry(struct intel_output *output, | 907 | static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, |
906 | uint8_t mode) | 908 | uint8_t mode) |
907 | { | 909 | { |
908 | uint8_t status; | 910 | uint8_t status; |
909 | 911 | ||
910 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | 912 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
911 | status = intel_sdvo_read_response(output, NULL, 0); | 913 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
912 | 914 | ||
913 | return (status == SDVO_CMD_STATUS_SUCCESS); | 915 | return (status == SDVO_CMD_STATUS_SUCCESS); |
914 | } | 916 | } |
915 | 917 | ||
916 | #if 0 | 918 | #if 0 |
917 | static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) | 919 | static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) |
918 | { | 920 | { |
919 | int i, j; | 921 | int i, j; |
920 | uint8_t set_buf_index[2]; | 922 | uint8_t set_buf_index[2]; |
@@ -923,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) | |||
923 | uint8_t buf[48]; | 925 | uint8_t buf[48]; |
924 | uint8_t *pos; | 926 | uint8_t *pos; |
925 | 927 | ||
926 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 928 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); |
927 | intel_sdvo_read_response(output, &av_split, 1); | 929 | intel_sdvo_read_response(encoder, &av_split, 1); |
928 | 930 | ||
929 | for (i = 0; i <= av_split; i++) { | 931 | for (i = 0; i <= av_split; i++) { |
930 | set_buf_index[0] = i; set_buf_index[1] = 0; | 932 | set_buf_index[0] = i; set_buf_index[1] = 0; |
931 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, | 933 | intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, |
932 | set_buf_index, 2); | 934 | set_buf_index, 2); |
933 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); | 935 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); |
934 | intel_sdvo_read_response(output, &buf_size, 1); | 936 | intel_sdvo_read_response(encoder, &buf_size, 1); |
935 | 937 | ||
936 | pos = buf; | 938 | pos = buf; |
937 | for (j = 0; j <= buf_size; j += 8) { | 939 | for (j = 0; j <= buf_size; j += 8) { |
938 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, | 940 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, |
939 | NULL, 0); | 941 | NULL, 0); |
940 | intel_sdvo_read_response(output, pos, 8); | 942 | intel_sdvo_read_response(encoder, pos, 8); |
941 | pos += 8; | 943 | pos += 8; |
942 | } | 944 | } |
943 | } | 945 | } |
944 | } | 946 | } |
945 | #endif | 947 | #endif |
946 | 948 | ||
947 | static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, | 949 | static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, |
948 | uint8_t *data, int8_t size, uint8_t tx_rate) | 950 | int index, |
951 | uint8_t *data, int8_t size, uint8_t tx_rate) | ||
949 | { | 952 | { |
950 | uint8_t set_buf_index[2]; | 953 | uint8_t set_buf_index[2]; |
951 | 954 | ||
952 | set_buf_index[0] = index; | 955 | set_buf_index[0] = index; |
953 | set_buf_index[1] = 0; | 956 | set_buf_index[1] = 0; |
954 | 957 | ||
955 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); | 958 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, |
959 | set_buf_index, 2); | ||
956 | 960 | ||
957 | for (; size > 0; size -= 8) { | 961 | for (; size > 0; size -= 8) { |
958 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); | 962 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); |
959 | data += 8; | 963 | data += 8; |
960 | } | 964 | } |
961 | 965 | ||
962 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 966 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
963 | } | 967 | } |
964 | 968 | ||
965 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 969 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
@@ -1034,7 +1038,7 @@ struct dip_infoframe { | |||
1034 | } __attribute__ ((packed)) u; | 1038 | } __attribute__ ((packed)) u; |
1035 | } __attribute__((packed)); | 1039 | } __attribute__((packed)); |
1036 | 1040 | ||
1037 | static void intel_sdvo_set_avi_infoframe(struct intel_output *output, | 1041 | static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, |
1038 | struct drm_display_mode * mode) | 1042 | struct drm_display_mode * mode) |
1039 | { | 1043 | { |
1040 | struct dip_infoframe avi_if = { | 1044 | struct dip_infoframe avi_if = { |
@@ -1045,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, | |||
1045 | 1049 | ||
1046 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 1050 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
1047 | 4 + avi_if.len); | 1051 | 4 + avi_if.len); |
1048 | intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, | 1052 | intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, |
1053 | 4 + avi_if.len, | ||
1049 | SDVO_HBUF_TX_VSYNC); | 1054 | SDVO_HBUF_TX_VSYNC); |
1050 | } | 1055 | } |
1051 | 1056 | ||
1052 | static void intel_sdvo_set_tv_format(struct intel_output *output) | 1057 | static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) |
1053 | { | 1058 | { |
1054 | 1059 | ||
1055 | struct intel_sdvo_tv_format format; | 1060 | struct intel_sdvo_tv_format format; |
1056 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1061 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1057 | uint32_t format_map, i; | 1062 | uint32_t format_map, i; |
1058 | uint8_t status; | 1063 | uint8_t status; |
1059 | 1064 | ||
@@ -1066,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output) | |||
1066 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 1071 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? |
1067 | sizeof(format) : sizeof(format_map)); | 1072 | sizeof(format) : sizeof(format_map)); |
1068 | 1073 | ||
1069 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, | 1074 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map, |
1070 | sizeof(format)); | 1075 | sizeof(format)); |
1071 | 1076 | ||
1072 | status = intel_sdvo_read_response(output, NULL, 0); | 1077 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
1073 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1078 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1074 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 1079 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", |
1075 | SDVO_NAME(sdvo_priv)); | 1080 | SDVO_NAME(sdvo_priv)); |
@@ -1079,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1079 | struct drm_display_mode *mode, | 1084 | struct drm_display_mode *mode, |
1080 | struct drm_display_mode *adjusted_mode) | 1085 | struct drm_display_mode *adjusted_mode) |
1081 | { | 1086 | { |
1082 | struct intel_output *output = enc_to_intel_output(encoder); | 1087 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1083 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 1088 | struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; |
1084 | 1089 | ||
1085 | if (dev_priv->is_tv) { | 1090 | if (dev_priv->is_tv) { |
1086 | struct intel_sdvo_dtd output_dtd; | 1091 | struct intel_sdvo_dtd output_dtd; |
@@ -1095,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1095 | 1100 | ||
1096 | /* Set output timings */ | 1101 | /* Set output timings */ |
1097 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1102 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1098 | intel_sdvo_set_target_output(output, | 1103 | intel_sdvo_set_target_output(intel_encoder, |
1099 | dev_priv->controlled_output); | 1104 | dev_priv->controlled_output); |
1100 | intel_sdvo_set_output_timing(output, &output_dtd); | 1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1101 | 1106 | ||
1102 | /* Set the input timing to the screen. Assume always input 0. */ | 1107 | /* Set the input timing to the screen. Assume always input 0. */ |
1103 | intel_sdvo_set_target_input(output, true, false); | 1108 | intel_sdvo_set_target_input(intel_encoder, true, false); |
1104 | 1109 | ||
1105 | 1110 | ||
1106 | success = intel_sdvo_create_preferred_input_timing(output, | 1111 | success = intel_sdvo_create_preferred_input_timing(intel_encoder, |
1107 | mode->clock / 10, | 1112 | mode->clock / 10, |
1108 | mode->hdisplay, | 1113 | mode->hdisplay, |
1109 | mode->vdisplay); | 1114 | mode->vdisplay); |
1110 | if (success) { | 1115 | if (success) { |
1111 | struct intel_sdvo_dtd input_dtd; | 1116 | struct intel_sdvo_dtd input_dtd; |
1112 | 1117 | ||
1113 | intel_sdvo_get_preferred_input_timing(output, | 1118 | intel_sdvo_get_preferred_input_timing(intel_encoder, |
1114 | &input_dtd); | 1119 | &input_dtd); |
1115 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1120 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1116 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | 1121 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; |
@@ -1133,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1133 | intel_sdvo_get_dtd_from_mode(&output_dtd, | 1138 | intel_sdvo_get_dtd_from_mode(&output_dtd, |
1134 | dev_priv->sdvo_lvds_fixed_mode); | 1139 | dev_priv->sdvo_lvds_fixed_mode); |
1135 | 1140 | ||
1136 | intel_sdvo_set_target_output(output, | 1141 | intel_sdvo_set_target_output(intel_encoder, |
1137 | dev_priv->controlled_output); | 1142 | dev_priv->controlled_output); |
1138 | intel_sdvo_set_output_timing(output, &output_dtd); | 1143 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); |
1139 | 1144 | ||
1140 | /* Set the input timing to the screen. Assume always input 0. */ | 1145 | /* Set the input timing to the screen. Assume always input 0. */ |
1141 | intel_sdvo_set_target_input(output, true, false); | 1146 | intel_sdvo_set_target_input(intel_encoder, true, false); |
1142 | 1147 | ||
1143 | 1148 | ||
1144 | success = intel_sdvo_create_preferred_input_timing( | 1149 | success = intel_sdvo_create_preferred_input_timing( |
1145 | output, | 1150 | intel_encoder, |
1146 | mode->clock / 10, | 1151 | mode->clock / 10, |
1147 | mode->hdisplay, | 1152 | mode->hdisplay, |
1148 | mode->vdisplay); | 1153 | mode->vdisplay); |
@@ -1150,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
1150 | if (success) { | 1155 | if (success) { |
1151 | struct intel_sdvo_dtd input_dtd; | 1156 | struct intel_sdvo_dtd input_dtd; |
1152 | 1157 | ||
1153 | intel_sdvo_get_preferred_input_timing(output, | 1158 | intel_sdvo_get_preferred_input_timing(intel_encoder, |
1154 | &input_dtd); | 1159 | &input_dtd); |
1155 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1160 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1156 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | 1161 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; |
@@ -1182,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1182 | struct drm_i915_private *dev_priv = dev->dev_private; | 1187 | struct drm_i915_private *dev_priv = dev->dev_private; |
1183 | struct drm_crtc *crtc = encoder->crtc; | 1188 | struct drm_crtc *crtc = encoder->crtc; |
1184 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1189 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1185 | struct intel_output *output = enc_to_intel_output(encoder); | 1190 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1186 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1191 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1187 | u32 sdvox = 0; | 1192 | u32 sdvox = 0; |
1188 | int sdvo_pixel_multiply; | 1193 | int sdvo_pixel_multiply; |
1189 | struct intel_sdvo_in_out_map in_out; | 1194 | struct intel_sdvo_in_out_map in_out; |
@@ -1202,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1202 | in_out.in0 = sdvo_priv->controlled_output; | 1207 | in_out.in0 = sdvo_priv->controlled_output; |
1203 | in_out.in1 = 0; | 1208 | in_out.in1 = 0; |
1204 | 1209 | ||
1205 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, | 1210 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, |
1206 | &in_out, sizeof(in_out)); | 1211 | &in_out, sizeof(in_out)); |
1207 | status = intel_sdvo_read_response(output, NULL, 0); | 1212 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); |
1208 | 1213 | ||
1209 | if (sdvo_priv->is_hdmi) { | 1214 | if (sdvo_priv->is_hdmi) { |
1210 | intel_sdvo_set_avi_infoframe(output, mode); | 1215 | intel_sdvo_set_avi_infoframe(intel_encoder, mode); |
1211 | sdvox |= SDVO_AUDIO_ENABLE; | 1216 | sdvox |= SDVO_AUDIO_ENABLE; |
1212 | } | 1217 | } |
1213 | 1218 | ||
@@ -1224,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1224 | */ | 1229 | */ |
1225 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1230 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1226 | /* Set the output timing to the screen */ | 1231 | /* Set the output timing to the screen */ |
1227 | intel_sdvo_set_target_output(output, | 1232 | intel_sdvo_set_target_output(intel_encoder, |
1228 | sdvo_priv->controlled_output); | 1233 | sdvo_priv->controlled_output); |
1229 | intel_sdvo_set_output_timing(output, &input_dtd); | 1234 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); |
1230 | } | 1235 | } |
1231 | 1236 | ||
1232 | /* Set the input timing to the screen. Assume always input 0. */ | 1237 | /* Set the input timing to the screen. Assume always input 0. */ |
1233 | intel_sdvo_set_target_input(output, true, false); | 1238 | intel_sdvo_set_target_input(intel_encoder, true, false); |
1234 | 1239 | ||
1235 | if (sdvo_priv->is_tv) | 1240 | if (sdvo_priv->is_tv) |
1236 | intel_sdvo_set_tv_format(output); | 1241 | intel_sdvo_set_tv_format(intel_encoder); |
1237 | 1242 | ||
1238 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1243 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
1239 | * provide the device with a timing it can support, if it supports that | 1244 | * provide the device with a timing it can support, if it supports that |
@@ -1241,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1241 | * output the preferred timing, and we don't support that currently. | 1246 | * output the preferred timing, and we don't support that currently. |
1242 | */ | 1247 | */ |
1243 | #if 0 | 1248 | #if 0 |
1244 | success = intel_sdvo_create_preferred_input_timing(output, clock, | 1249 | success = intel_sdvo_create_preferred_input_timing(encoder, clock, |
1245 | width, height); | 1250 | width, height); |
1246 | if (success) { | 1251 | if (success) { |
1247 | struct intel_sdvo_dtd *input_dtd; | 1252 | struct intel_sdvo_dtd *input_dtd; |
1248 | 1253 | ||
1249 | intel_sdvo_get_preferred_input_timing(output, &input_dtd); | 1254 | intel_sdvo_get_preferred_input_timing(encoder, &input_dtd); |
1250 | intel_sdvo_set_input_timing(output, &input_dtd); | 1255 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1251 | } | 1256 | } |
1252 | #else | 1257 | #else |
1253 | intel_sdvo_set_input_timing(output, &input_dtd); | 1258 | intel_sdvo_set_input_timing(intel_encoder, &input_dtd); |
1254 | #endif | 1259 | #endif |
1255 | 1260 | ||
1256 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1261 | switch (intel_sdvo_get_pixel_multiplier(mode)) { |
1257 | case 1: | 1262 | case 1: |
1258 | intel_sdvo_set_clock_rate_mult(output, | 1263 | intel_sdvo_set_clock_rate_mult(intel_encoder, |
1259 | SDVO_CLOCK_RATE_MULT_1X); | 1264 | SDVO_CLOCK_RATE_MULT_1X); |
1260 | break; | 1265 | break; |
1261 | case 2: | 1266 | case 2: |
1262 | intel_sdvo_set_clock_rate_mult(output, | 1267 | intel_sdvo_set_clock_rate_mult(intel_encoder, |
1263 | SDVO_CLOCK_RATE_MULT_2X); | 1268 | SDVO_CLOCK_RATE_MULT_2X); |
1264 | break; | 1269 | break; |
1265 | case 4: | 1270 | case 4: |
1266 | intel_sdvo_set_clock_rate_mult(output, | 1271 | intel_sdvo_set_clock_rate_mult(intel_encoder, |
1267 | SDVO_CLOCK_RATE_MULT_4X); | 1272 | SDVO_CLOCK_RATE_MULT_4X); |
1268 | break; | 1273 | break; |
1269 | } | 1274 | } |
@@ -1274,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1274 | SDVO_VSYNC_ACTIVE_HIGH | | 1279 | SDVO_VSYNC_ACTIVE_HIGH | |
1275 | SDVO_HSYNC_ACTIVE_HIGH; | 1280 | SDVO_HSYNC_ACTIVE_HIGH; |
1276 | } else { | 1281 | } else { |
1277 | sdvox |= I915_READ(sdvo_priv->output_device); | 1282 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); |
1278 | switch (sdvo_priv->output_device) { | 1283 | switch (sdvo_priv->sdvo_reg) { |
1279 | case SDVOB: | 1284 | case SDVOB: |
1280 | sdvox &= SDVOB_PRESERVE_MASK; | 1285 | sdvox &= SDVOB_PRESERVE_MASK; |
1281 | break; | 1286 | break; |
@@ -1299,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1299 | 1304 | ||
1300 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | 1305 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) |
1301 | sdvox |= SDVO_STALL_SELECT; | 1306 | sdvox |= SDVO_STALL_SELECT; |
1302 | intel_sdvo_write_sdvox(output, sdvox); | 1307 | intel_sdvo_write_sdvox(intel_encoder, sdvox); |
1303 | } | 1308 | } |
1304 | 1309 | ||
1305 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1310 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
1306 | { | 1311 | { |
1307 | struct drm_device *dev = encoder->dev; | 1312 | struct drm_device *dev = encoder->dev; |
1308 | struct drm_i915_private *dev_priv = dev->dev_private; | 1313 | struct drm_i915_private *dev_priv = dev->dev_private; |
1309 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 1314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1310 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1315 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1311 | u32 temp; | 1316 | u32 temp; |
1312 | 1317 | ||
1313 | if (mode != DRM_MODE_DPMS_ON) { | 1318 | if (mode != DRM_MODE_DPMS_ON) { |
1314 | intel_sdvo_set_active_outputs(intel_output, 0); | 1319 | intel_sdvo_set_active_outputs(intel_encoder, 0); |
1315 | if (0) | 1320 | if (0) |
1316 | intel_sdvo_set_encoder_power_state(intel_output, mode); | 1321 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); |
1317 | 1322 | ||
1318 | if (mode == DRM_MODE_DPMS_OFF) { | 1323 | if (mode == DRM_MODE_DPMS_OFF) { |
1319 | temp = I915_READ(sdvo_priv->output_device); | 1324 | temp = I915_READ(sdvo_priv->sdvo_reg); |
1320 | if ((temp & SDVO_ENABLE) != 0) { | 1325 | if ((temp & SDVO_ENABLE) != 0) { |
1321 | intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE); | 1326 | intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); |
1322 | } | 1327 | } |
1323 | } | 1328 | } |
1324 | } else { | 1329 | } else { |
@@ -1326,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1326 | int i; | 1331 | int i; |
1327 | u8 status; | 1332 | u8 status; |
1328 | 1333 | ||
1329 | temp = I915_READ(sdvo_priv->output_device); | 1334 | temp = I915_READ(sdvo_priv->sdvo_reg); |
1330 | if ((temp & SDVO_ENABLE) == 0) | 1335 | if ((temp & SDVO_ENABLE) == 0) |
1331 | intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE); | 1336 | intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); |
1332 | for (i = 0; i < 2; i++) | 1337 | for (i = 0; i < 2; i++) |
1333 | intel_wait_for_vblank(dev); | 1338 | intel_wait_for_vblank(dev); |
1334 | 1339 | ||
1335 | status = intel_sdvo_get_trained_inputs(intel_output, &input1, | 1340 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, |
1336 | &input2); | 1341 | &input2); |
1337 | 1342 | ||
1338 | 1343 | ||
@@ -1346,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1346 | } | 1351 | } |
1347 | 1352 | ||
1348 | if (0) | 1353 | if (0) |
1349 | intel_sdvo_set_encoder_power_state(intel_output, mode); | 1354 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); |
1350 | intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); | 1355 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output); |
1351 | } | 1356 | } |
1352 | return; | 1357 | return; |
1353 | } | 1358 | } |
@@ -1356,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector) | |||
1356 | { | 1361 | { |
1357 | struct drm_device *dev = connector->dev; | 1362 | struct drm_device *dev = connector->dev; |
1358 | struct drm_i915_private *dev_priv = dev->dev_private; | 1363 | struct drm_i915_private *dev_priv = dev->dev_private; |
1359 | struct intel_output *intel_output = to_intel_output(connector); | 1364 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1360 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1365 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1361 | int o; | 1366 | int o; |
1362 | 1367 | ||
1363 | sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output); | 1368 | sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); |
1364 | intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs); | 1369 | intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs); |
1365 | 1370 | ||
1366 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | 1371 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { |
1367 | intel_sdvo_set_target_input(intel_output, true, false); | 1372 | intel_sdvo_set_target_input(intel_encoder, true, false); |
1368 | intel_sdvo_get_input_timing(intel_output, | 1373 | intel_sdvo_get_input_timing(intel_encoder, |
1369 | &sdvo_priv->save_input_dtd_1); | 1374 | &sdvo_priv->save_input_dtd_1); |
1370 | } | 1375 | } |
1371 | 1376 | ||
1372 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | 1377 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { |
1373 | intel_sdvo_set_target_input(intel_output, false, true); | 1378 | intel_sdvo_set_target_input(intel_encoder, false, true); |
1374 | intel_sdvo_get_input_timing(intel_output, | 1379 | intel_sdvo_get_input_timing(intel_encoder, |
1375 | &sdvo_priv->save_input_dtd_2); | 1380 | &sdvo_priv->save_input_dtd_2); |
1376 | } | 1381 | } |
1377 | 1382 | ||
@@ -1380,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector) | |||
1380 | u16 this_output = (1 << o); | 1385 | u16 this_output = (1 << o); |
1381 | if (sdvo_priv->caps.output_flags & this_output) | 1386 | if (sdvo_priv->caps.output_flags & this_output) |
1382 | { | 1387 | { |
1383 | intel_sdvo_set_target_output(intel_output, this_output); | 1388 | intel_sdvo_set_target_output(intel_encoder, this_output); |
1384 | intel_sdvo_get_output_timing(intel_output, | 1389 | intel_sdvo_get_output_timing(intel_encoder, |
1385 | &sdvo_priv->save_output_dtd[o]); | 1390 | &sdvo_priv->save_output_dtd[o]); |
1386 | } | 1391 | } |
1387 | } | 1392 | } |
@@ -1389,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector) | |||
1389 | /* XXX: Save TV format/enhancements. */ | 1394 | /* XXX: Save TV format/enhancements. */ |
1390 | } | 1395 | } |
1391 | 1396 | ||
1392 | sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); | 1397 | sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg); |
1393 | } | 1398 | } |
1394 | 1399 | ||
1395 | static void intel_sdvo_restore(struct drm_connector *connector) | 1400 | static void intel_sdvo_restore(struct drm_connector *connector) |
1396 | { | 1401 | { |
1397 | struct drm_device *dev = connector->dev; | 1402 | struct drm_device *dev = connector->dev; |
1398 | struct intel_output *intel_output = to_intel_output(connector); | 1403 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1399 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1404 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1400 | int o; | 1405 | int o; |
1401 | int i; | 1406 | int i; |
1402 | bool input1, input2; | 1407 | bool input1, input2; |
1403 | u8 status; | 1408 | u8 status; |
1404 | 1409 | ||
1405 | intel_sdvo_set_active_outputs(intel_output, 0); | 1410 | intel_sdvo_set_active_outputs(intel_encoder, 0); |
1406 | 1411 | ||
1407 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) | 1412 | for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) |
1408 | { | 1413 | { |
1409 | u16 this_output = (1 << o); | 1414 | u16 this_output = (1 << o); |
1410 | if (sdvo_priv->caps.output_flags & this_output) { | 1415 | if (sdvo_priv->caps.output_flags & this_output) { |
1411 | intel_sdvo_set_target_output(intel_output, this_output); | 1416 | intel_sdvo_set_target_output(intel_encoder, this_output); |
1412 | intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]); | 1417 | intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); |
1413 | } | 1418 | } |
1414 | } | 1419 | } |
1415 | 1420 | ||
1416 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { | 1421 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { |
1417 | intel_sdvo_set_target_input(intel_output, true, false); | 1422 | intel_sdvo_set_target_input(intel_encoder, true, false); |
1418 | intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1); | 1423 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); |
1419 | } | 1424 | } |
1420 | 1425 | ||
1421 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { | 1426 | if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { |
1422 | intel_sdvo_set_target_input(intel_output, false, true); | 1427 | intel_sdvo_set_target_input(intel_encoder, false, true); |
1423 | intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2); | 1428 | intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); |
1424 | } | 1429 | } |
1425 | 1430 | ||
1426 | intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); | 1431 | intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult); |
1427 | 1432 | ||
1428 | if (sdvo_priv->is_tv) { | 1433 | if (sdvo_priv->is_tv) { |
1429 | /* XXX: Restore TV format/enhancements. */ | 1434 | /* XXX: Restore TV format/enhancements. */ |
1430 | } | 1435 | } |
1431 | 1436 | ||
1432 | intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); | 1437 | intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX); |
1433 | 1438 | ||
1434 | if (sdvo_priv->save_SDVOX & SDVO_ENABLE) | 1439 | if (sdvo_priv->save_SDVOX & SDVO_ENABLE) |
1435 | { | 1440 | { |
1436 | for (i = 0; i < 2; i++) | 1441 | for (i = 0; i < 2; i++) |
1437 | intel_wait_for_vblank(dev); | 1442 | intel_wait_for_vblank(dev); |
1438 | status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); | 1443 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); |
1439 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) | 1444 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) |
1440 | DRM_DEBUG_KMS("First %s output reported failure to " | 1445 | DRM_DEBUG_KMS("First %s output reported failure to " |
1441 | "sync\n", SDVO_NAME(sdvo_priv)); | 1446 | "sync\n", SDVO_NAME(sdvo_priv)); |
1442 | } | 1447 | } |
1443 | 1448 | ||
1444 | intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); | 1449 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs); |
1445 | } | 1450 | } |
1446 | 1451 | ||
1447 | static int intel_sdvo_mode_valid(struct drm_connector *connector, | 1452 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
1448 | struct drm_display_mode *mode) | 1453 | struct drm_display_mode *mode) |
1449 | { | 1454 | { |
1450 | struct intel_output *intel_output = to_intel_output(connector); | 1455 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1451 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1456 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1452 | 1457 | ||
1453 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1458 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
1454 | return MODE_NO_DBLESCAN; | 1459 | return MODE_NO_DBLESCAN; |
@@ -1473,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1473 | return MODE_OK; | 1478 | return MODE_OK; |
1474 | } | 1479 | } |
1475 | 1480 | ||
1476 | static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps) | 1481 | static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) |
1477 | { | 1482 | { |
1478 | u8 status; | 1483 | u8 status; |
1479 | 1484 | ||
1480 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | 1485 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); |
1481 | status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps)); | 1486 | status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); |
1482 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1487 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1483 | return false; | 1488 | return false; |
1484 | 1489 | ||
@@ -1488,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc | |||
1488 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1493 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
1489 | { | 1494 | { |
1490 | struct drm_connector *connector = NULL; | 1495 | struct drm_connector *connector = NULL; |
1491 | struct intel_output *iout = NULL; | 1496 | struct intel_encoder *iout = NULL; |
1492 | struct intel_sdvo_priv *sdvo; | 1497 | struct intel_sdvo_priv *sdvo; |
1493 | 1498 | ||
1494 | /* find the sdvo connector */ | 1499 | /* find the sdvo connector */ |
1495 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1500 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1496 | iout = to_intel_output(connector); | 1501 | iout = to_intel_encoder(connector); |
1497 | 1502 | ||
1498 | if (iout->type != INTEL_OUTPUT_SDVO) | 1503 | if (iout->type != INTEL_OUTPUT_SDVO) |
1499 | continue; | 1504 | continue; |
1500 | 1505 | ||
1501 | sdvo = iout->dev_priv; | 1506 | sdvo = iout->dev_priv; |
1502 | 1507 | ||
1503 | if (sdvo->output_device == SDVOB && sdvoB) | 1508 | if (sdvo->sdvo_reg == SDVOB && sdvoB) |
1504 | return connector; | 1509 | return connector; |
1505 | 1510 | ||
1506 | if (sdvo->output_device == SDVOC && !sdvoB) | 1511 | if (sdvo->sdvo_reg == SDVOC && !sdvoB) |
1507 | return connector; | 1512 | return connector; |
1508 | 1513 | ||
1509 | } | 1514 | } |
@@ -1515,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
1515 | { | 1520 | { |
1516 | u8 response[2]; | 1521 | u8 response[2]; |
1517 | u8 status; | 1522 | u8 status; |
1518 | struct intel_output *intel_output; | 1523 | struct intel_encoder *intel_encoder; |
1519 | DRM_DEBUG_KMS("\n"); | 1524 | DRM_DEBUG_KMS("\n"); |
1520 | 1525 | ||
1521 | if (!connector) | 1526 | if (!connector) |
1522 | return 0; | 1527 | return 0; |
1523 | 1528 | ||
1524 | intel_output = to_intel_output(connector); | 1529 | intel_encoder = to_intel_encoder(connector); |
1525 | 1530 | ||
1526 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1531 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
1527 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1532 | status = intel_sdvo_read_response(intel_encoder, &response, 2); |
1528 | 1533 | ||
1529 | if (response[0] !=0) | 1534 | if (response[0] !=0) |
1530 | return 1; | 1535 | return 1; |
@@ -1536,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1536 | { | 1541 | { |
1537 | u8 response[2]; | 1542 | u8 response[2]; |
1538 | u8 status; | 1543 | u8 status; |
1539 | struct intel_output *intel_output = to_intel_output(connector); | 1544 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1540 | 1545 | ||
1541 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1546 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1542 | intel_sdvo_read_response(intel_output, &response, 2); | 1547 | intel_sdvo_read_response(intel_encoder, &response, 2); |
1543 | 1548 | ||
1544 | if (on) { | 1549 | if (on) { |
1545 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1550 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
1546 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1551 | status = intel_sdvo_read_response(intel_encoder, &response, 2); |
1547 | 1552 | ||
1548 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1553 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1549 | } else { | 1554 | } else { |
1550 | response[0] = 0; | 1555 | response[0] = 0; |
1551 | response[1] = 0; | 1556 | response[1] = 0; |
1552 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1557 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1553 | } | 1558 | } |
1554 | 1559 | ||
1555 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1560 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1556 | intel_sdvo_read_response(intel_output, &response, 2); | 1561 | intel_sdvo_read_response(intel_encoder, &response, 2); |
1557 | } | 1562 | } |
1558 | 1563 | ||
1559 | static bool | 1564 | static bool |
1560 | intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | 1565 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) |
1561 | { | 1566 | { |
1562 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1567 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1563 | int caps = 0; | 1568 | int caps = 0; |
1564 | 1569 | ||
1565 | if (sdvo_priv->caps.output_flags & | 1570 | if (sdvo_priv->caps.output_flags & |
@@ -1593,11 +1598,11 @@ static struct drm_connector * | |||
1593 | intel_find_analog_connector(struct drm_device *dev) | 1598 | intel_find_analog_connector(struct drm_device *dev) |
1594 | { | 1599 | { |
1595 | struct drm_connector *connector; | 1600 | struct drm_connector *connector; |
1596 | struct intel_output *intel_output; | 1601 | struct intel_encoder *intel_encoder; |
1597 | 1602 | ||
1598 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1603 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1599 | intel_output = to_intel_output(connector); | 1604 | intel_encoder = to_intel_encoder(connector); |
1600 | if (intel_output->type == INTEL_OUTPUT_ANALOG) | 1605 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) |
1601 | return connector; | 1606 | return connector; |
1602 | } | 1607 | } |
1603 | return NULL; | 1608 | return NULL; |
@@ -1622,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev) | |||
1622 | enum drm_connector_status | 1627 | enum drm_connector_status |
1623 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1628 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) |
1624 | { | 1629 | { |
1625 | struct intel_output *intel_output = to_intel_output(connector); | 1630 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1626 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1631 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1627 | enum drm_connector_status status = connector_status_connected; | 1632 | enum drm_connector_status status = connector_status_connected; |
1628 | struct edid *edid = NULL; | 1633 | struct edid *edid = NULL; |
1629 | 1634 | ||
1630 | edid = drm_get_edid(&intel_output->base, | 1635 | edid = drm_get_edid(&intel_encoder->base, |
1631 | intel_output->ddc_bus); | 1636 | intel_encoder->ddc_bus); |
1632 | 1637 | ||
1633 | /* This is only applied to SDVO cards with multiple outputs */ | 1638 | /* This is only applied to SDVO cards with multiple outputs */ |
1634 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { | 1639 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { |
1635 | uint8_t saved_ddc, temp_ddc; | 1640 | uint8_t saved_ddc, temp_ddc; |
1636 | saved_ddc = sdvo_priv->ddc_bus; | 1641 | saved_ddc = sdvo_priv->ddc_bus; |
1637 | temp_ddc = sdvo_priv->ddc_bus >> 1; | 1642 | temp_ddc = sdvo_priv->ddc_bus >> 1; |
@@ -1641,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1641 | */ | 1646 | */ |
1642 | while(temp_ddc > 1) { | 1647 | while(temp_ddc > 1) { |
1643 | sdvo_priv->ddc_bus = temp_ddc; | 1648 | sdvo_priv->ddc_bus = temp_ddc; |
1644 | edid = drm_get_edid(&intel_output->base, | 1649 | edid = drm_get_edid(&intel_encoder->base, |
1645 | intel_output->ddc_bus); | 1650 | intel_encoder->ddc_bus); |
1646 | if (edid) { | 1651 | if (edid) { |
1647 | /* | 1652 | /* |
1648 | * When we can get the EDID, maybe it is the | 1653 | * When we can get the EDID, maybe it is the |
@@ -1661,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1661 | */ | 1666 | */ |
1662 | if (edid == NULL && | 1667 | if (edid == NULL && |
1663 | sdvo_priv->analog_ddc_bus && | 1668 | sdvo_priv->analog_ddc_bus && |
1664 | !intel_analog_is_connected(intel_output->base.dev)) | 1669 | !intel_analog_is_connected(intel_encoder->base.dev)) |
1665 | edid = drm_get_edid(&intel_output->base, | 1670 | edid = drm_get_edid(&intel_encoder->base, |
1666 | sdvo_priv->analog_ddc_bus); | 1671 | sdvo_priv->analog_ddc_bus); |
1667 | if (edid != NULL) { | 1672 | if (edid != NULL) { |
1668 | /* Don't report the output as connected if it's a DVI-I | 1673 | /* Don't report the output as connected if it's a DVI-I |
@@ -1677,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1677 | } | 1682 | } |
1678 | 1683 | ||
1679 | kfree(edid); | 1684 | kfree(edid); |
1680 | intel_output->base.display_info.raw_edid = NULL; | 1685 | intel_encoder->base.display_info.raw_edid = NULL; |
1681 | 1686 | ||
1682 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1687 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
1683 | status = connector_status_disconnected; | 1688 | status = connector_status_disconnected; |
@@ -1689,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1689 | { | 1694 | { |
1690 | uint16_t response; | 1695 | uint16_t response; |
1691 | u8 status; | 1696 | u8 status; |
1692 | struct intel_output *intel_output = to_intel_output(connector); | 1697 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1693 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1698 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1694 | 1699 | ||
1695 | intel_sdvo_write_cmd(intel_output, | 1700 | intel_sdvo_write_cmd(intel_encoder, |
1696 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1701 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
1697 | if (sdvo_priv->is_tv) { | 1702 | if (sdvo_priv->is_tv) { |
1698 | /* add 30ms delay when the output type is SDVO-TV */ | 1703 | /* add 30ms delay when the output type is SDVO-TV */ |
1699 | mdelay(30); | 1704 | mdelay(30); |
1700 | } | 1705 | } |
1701 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1706 | status = intel_sdvo_read_response(intel_encoder, &response, 2); |
1702 | 1707 | ||
1703 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1708 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
1704 | 1709 | ||
@@ -1708,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1708 | if (response == 0) | 1713 | if (response == 0) |
1709 | return connector_status_disconnected; | 1714 | return connector_status_disconnected; |
1710 | 1715 | ||
1711 | if (intel_sdvo_multifunc_encoder(intel_output) && | 1716 | if (intel_sdvo_multifunc_encoder(intel_encoder) && |
1712 | sdvo_priv->attached_output != response) { | 1717 | sdvo_priv->attached_output != response) { |
1713 | if (sdvo_priv->controlled_output != response && | 1718 | if (sdvo_priv->controlled_output != response && |
1714 | intel_sdvo_output_setup(intel_output, response) != true) | 1719 | intel_sdvo_output_setup(intel_encoder, response) != true) |
1715 | return connector_status_unknown; | 1720 | return connector_status_unknown; |
1716 | sdvo_priv->attached_output = response; | 1721 | sdvo_priv->attached_output = response; |
1717 | } | 1722 | } |
@@ -1720,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1720 | 1725 | ||
1721 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1726 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1722 | { | 1727 | { |
1723 | struct intel_output *intel_output = to_intel_output(connector); | 1728 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1724 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1729 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1725 | int num_modes; | 1730 | int num_modes; |
1726 | 1731 | ||
1727 | /* set the bus switch and get the modes */ | 1732 | /* set the bus switch and get the modes */ |
1728 | num_modes = intel_ddc_get_modes(intel_output); | 1733 | num_modes = intel_ddc_get_modes(intel_encoder); |
1729 | 1734 | ||
1730 | /* | 1735 | /* |
1731 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1736 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1735,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1735 | */ | 1740 | */ |
1736 | if (num_modes == 0 && | 1741 | if (num_modes == 0 && |
1737 | sdvo_priv->analog_ddc_bus && | 1742 | sdvo_priv->analog_ddc_bus && |
1738 | !intel_analog_is_connected(intel_output->base.dev)) { | 1743 | !intel_analog_is_connected(intel_encoder->base.dev)) { |
1739 | struct i2c_adapter *digital_ddc_bus; | 1744 | struct i2c_adapter *digital_ddc_bus; |
1740 | 1745 | ||
1741 | /* Switch to the analog ddc bus and try that | 1746 | /* Switch to the analog ddc bus and try that |
1742 | */ | 1747 | */ |
1743 | digital_ddc_bus = intel_output->ddc_bus; | 1748 | digital_ddc_bus = intel_encoder->ddc_bus; |
1744 | intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; | 1749 | intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; |
1745 | 1750 | ||
1746 | (void) intel_ddc_get_modes(intel_output); | 1751 | (void) intel_ddc_get_modes(intel_encoder); |
1747 | 1752 | ||
1748 | intel_output->ddc_bus = digital_ddc_bus; | 1753 | intel_encoder->ddc_bus = digital_ddc_bus; |
1749 | } | 1754 | } |
1750 | } | 1755 | } |
1751 | 1756 | ||
@@ -1816,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1816 | 1821 | ||
1817 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1822 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1818 | { | 1823 | { |
1819 | struct intel_output *output = to_intel_output(connector); | 1824 | struct intel_encoder *output = to_intel_encoder(connector); |
1820 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1825 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
1821 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1826 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1822 | uint32_t reply = 0, format_map = 0; | 1827 | uint32_t reply = 0, format_map = 0; |
@@ -1858,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1858 | 1863 | ||
1859 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1864 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1860 | { | 1865 | { |
1861 | struct intel_output *intel_output = to_intel_output(connector); | 1866 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1862 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1867 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1863 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1868 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1864 | struct drm_display_mode *newmode; | 1869 | struct drm_display_mode *newmode; |
1865 | 1870 | ||
1866 | /* | 1871 | /* |
@@ -1868,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1868 | * Assume that the preferred modes are | 1873 | * Assume that the preferred modes are |
1869 | * arranged in priority order. | 1874 | * arranged in priority order. |
1870 | */ | 1875 | */ |
1871 | intel_ddc_get_modes(intel_output); | 1876 | intel_ddc_get_modes(intel_encoder); |
1872 | if (list_empty(&connector->probed_modes) == false) | 1877 | if (list_empty(&connector->probed_modes) == false) |
1873 | goto end; | 1878 | goto end; |
1874 | 1879 | ||
@@ -1897,7 +1902,7 @@ end: | |||
1897 | 1902 | ||
1898 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1903 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1899 | { | 1904 | { |
1900 | struct intel_output *output = to_intel_output(connector); | 1905 | struct intel_encoder *output = to_intel_encoder(connector); |
1901 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1906 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
1902 | 1907 | ||
1903 | if (sdvo_priv->is_tv) | 1908 | if (sdvo_priv->is_tv) |
@@ -1915,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1915 | static | 1920 | static |
1916 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1921 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
1917 | { | 1922 | { |
1918 | struct intel_output *intel_output = to_intel_output(connector); | 1923 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1919 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1924 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1920 | struct drm_device *dev = connector->dev; | 1925 | struct drm_device *dev = connector->dev; |
1921 | 1926 | ||
1922 | if (sdvo_priv->is_tv) { | 1927 | if (sdvo_priv->is_tv) { |
@@ -1953,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1953 | 1958 | ||
1954 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1959 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1955 | { | 1960 | { |
1956 | struct intel_output *intel_output = to_intel_output(connector); | 1961 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1957 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1962 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1958 | 1963 | ||
1959 | if (intel_output->i2c_bus) | 1964 | if (intel_encoder->i2c_bus) |
1960 | intel_i2c_destroy(intel_output->i2c_bus); | 1965 | intel_i2c_destroy(intel_encoder->i2c_bus); |
1961 | if (intel_output->ddc_bus) | 1966 | if (intel_encoder->ddc_bus) |
1962 | intel_i2c_destroy(intel_output->ddc_bus); | 1967 | intel_i2c_destroy(intel_encoder->ddc_bus); |
1963 | if (sdvo_priv->analog_ddc_bus) | 1968 | if (sdvo_priv->analog_ddc_bus) |
1964 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 1969 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); |
1965 | 1970 | ||
@@ -1977,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
1977 | drm_sysfs_connector_remove(connector); | 1982 | drm_sysfs_connector_remove(connector); |
1978 | drm_connector_cleanup(connector); | 1983 | drm_connector_cleanup(connector); |
1979 | 1984 | ||
1980 | kfree(intel_output); | 1985 | kfree(intel_encoder); |
1981 | } | 1986 | } |
1982 | 1987 | ||
1983 | static int | 1988 | static int |
@@ -1985,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1985 | struct drm_property *property, | 1990 | struct drm_property *property, |
1986 | uint64_t val) | 1991 | uint64_t val) |
1987 | { | 1992 | { |
1988 | struct intel_output *intel_output = to_intel_output(connector); | 1993 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1989 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1994 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
1990 | struct drm_encoder *encoder = &intel_output->enc; | 1995 | struct drm_encoder *encoder = &intel_encoder->enc; |
1991 | struct drm_crtc *crtc = encoder->crtc; | 1996 | struct drm_crtc *crtc = encoder->crtc; |
1992 | int ret = 0; | 1997 | int ret = 0; |
1993 | bool changed = false; | 1998 | bool changed = false; |
@@ -2095,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
2095 | sdvo_priv->cur_brightness = temp_value; | 2100 | sdvo_priv->cur_brightness = temp_value; |
2096 | } | 2101 | } |
2097 | if (cmd) { | 2102 | if (cmd) { |
2098 | intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); | 2103 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); |
2099 | status = intel_sdvo_read_response(intel_output, | 2104 | status = intel_sdvo_read_response(intel_encoder, |
2100 | NULL, 0); | 2105 | NULL, 0); |
2101 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2106 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2102 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | 2107 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); |
@@ -2191,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) | |||
2191 | } | 2196 | } |
2192 | 2197 | ||
2193 | static bool | 2198 | static bool |
2194 | intel_sdvo_get_digital_encoding_mode(struct intel_output *output) | 2199 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output) |
2195 | { | 2200 | { |
2196 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 2201 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
2197 | uint8_t status; | 2202 | uint8_t status; |
@@ -2205,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output) | |||
2205 | return true; | 2210 | return true; |
2206 | } | 2211 | } |
2207 | 2212 | ||
2208 | static struct intel_output * | 2213 | static struct intel_encoder * |
2209 | intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | 2214 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) |
2210 | { | 2215 | { |
2211 | struct drm_device *dev = chan->drm_dev; | 2216 | struct drm_device *dev = chan->drm_dev; |
2212 | struct drm_connector *connector; | 2217 | struct drm_connector *connector; |
2213 | struct intel_output *intel_output = NULL; | 2218 | struct intel_encoder *intel_encoder = NULL; |
2214 | 2219 | ||
2215 | list_for_each_entry(connector, | 2220 | list_for_each_entry(connector, |
2216 | &dev->mode_config.connector_list, head) { | 2221 | &dev->mode_config.connector_list, head) { |
2217 | if (to_intel_output(connector)->ddc_bus == &chan->adapter) { | 2222 | if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { |
2218 | intel_output = to_intel_output(connector); | 2223 | intel_encoder = to_intel_encoder(connector); |
2219 | break; | 2224 | break; |
2220 | } | 2225 | } |
2221 | } | 2226 | } |
2222 | return intel_output; | 2227 | return intel_encoder; |
2223 | } | 2228 | } |
2224 | 2229 | ||
2225 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 2230 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
2226 | struct i2c_msg msgs[], int num) | 2231 | struct i2c_msg msgs[], int num) |
2227 | { | 2232 | { |
2228 | struct intel_output *intel_output; | 2233 | struct intel_encoder *intel_encoder; |
2229 | struct intel_sdvo_priv *sdvo_priv; | 2234 | struct intel_sdvo_priv *sdvo_priv; |
2230 | struct i2c_algo_bit_data *algo_data; | 2235 | struct i2c_algo_bit_data *algo_data; |
2231 | const struct i2c_algorithm *algo; | 2236 | const struct i2c_algorithm *algo; |
2232 | 2237 | ||
2233 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 2238 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
2234 | intel_output = | 2239 | intel_encoder = |
2235 | intel_sdvo_chan_to_intel_output( | 2240 | intel_sdvo_chan_to_intel_encoder( |
2236 | (struct intel_i2c_chan *)(algo_data->data)); | 2241 | (struct intel_i2c_chan *)(algo_data->data)); |
2237 | if (intel_output == NULL) | 2242 | if (intel_encoder == NULL) |
2238 | return -EINVAL; | 2243 | return -EINVAL; |
2239 | 2244 | ||
2240 | sdvo_priv = intel_output->dev_priv; | 2245 | sdvo_priv = intel_encoder->dev_priv; |
2241 | algo = intel_output->i2c_bus->algo; | 2246 | algo = intel_encoder->i2c_bus->algo; |
2242 | 2247 | ||
2243 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | 2248 | intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); |
2244 | return algo->master_xfer(i2c_adap, msgs, num); | 2249 | return algo->master_xfer(i2c_adap, msgs, num); |
2245 | } | 2250 | } |
2246 | 2251 | ||
@@ -2249,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { | |||
2249 | }; | 2254 | }; |
2250 | 2255 | ||
2251 | static u8 | 2256 | static u8 |
2252 | intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | 2257 | intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) |
2253 | { | 2258 | { |
2254 | struct drm_i915_private *dev_priv = dev->dev_private; | 2259 | struct drm_i915_private *dev_priv = dev->dev_private; |
2255 | struct sdvo_device_mapping *my_mapping, *other_mapping; | 2260 | struct sdvo_device_mapping *my_mapping, *other_mapping; |
2256 | 2261 | ||
2257 | if (output_device == SDVOB) { | 2262 | if (sdvo_reg == SDVOB) { |
2258 | my_mapping = &dev_priv->sdvo_mappings[0]; | 2263 | my_mapping = &dev_priv->sdvo_mappings[0]; |
2259 | other_mapping = &dev_priv->sdvo_mappings[1]; | 2264 | other_mapping = &dev_priv->sdvo_mappings[1]; |
2260 | } else { | 2265 | } else { |
@@ -2279,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | |||
2279 | /* No SDVO device info is found for another DVO port, | 2284 | /* No SDVO device info is found for another DVO port, |
2280 | * so use mapping assumption we had before BIOS parsing. | 2285 | * so use mapping assumption we had before BIOS parsing. |
2281 | */ | 2286 | */ |
2282 | if (output_device == SDVOB) | 2287 | if (sdvo_reg == SDVOB) |
2283 | return 0x70; | 2288 | return 0x70; |
2284 | else | 2289 | else |
2285 | return 0x72; | 2290 | return 0x72; |
@@ -2305,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = { | |||
2305 | }; | 2310 | }; |
2306 | 2311 | ||
2307 | static bool | 2312 | static bool |
2308 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | 2313 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) |
2309 | { | 2314 | { |
2310 | struct drm_connector *connector = &intel_output->base; | 2315 | struct drm_connector *connector = &intel_encoder->base; |
2311 | struct drm_encoder *encoder = &intel_output->enc; | 2316 | struct drm_encoder *encoder = &intel_encoder->enc; |
2312 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 2317 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2313 | bool ret = true, registered = false; | 2318 | bool ret = true, registered = false; |
2314 | 2319 | ||
2315 | sdvo_priv->is_tv = false; | 2320 | sdvo_priv->is_tv = false; |
2316 | intel_output->needs_tv_clock = false; | 2321 | intel_encoder->needs_tv_clock = false; |
2317 | sdvo_priv->is_lvds = false; | 2322 | sdvo_priv->is_lvds = false; |
2318 | 2323 | ||
2319 | if (device_is_registered(&connector->kdev)) { | 2324 | if (device_is_registered(&connector->kdev)) { |
@@ -2331,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2331 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2336 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
2332 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2337 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2333 | 2338 | ||
2334 | if (intel_sdvo_get_supp_encode(intel_output, | 2339 | if (intel_sdvo_get_supp_encode(intel_encoder, |
2335 | &sdvo_priv->encode) && | 2340 | &sdvo_priv->encode) && |
2336 | intel_sdvo_get_digital_encoding_mode(intel_output) && | 2341 | intel_sdvo_get_digital_encoding_mode(intel_encoder) && |
2337 | sdvo_priv->is_hdmi) { | 2342 | sdvo_priv->is_hdmi) { |
2338 | /* enable hdmi encoding mode if supported */ | 2343 | /* enable hdmi encoding mode if supported */ |
2339 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | 2344 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); |
2340 | intel_sdvo_set_colorimetry(intel_output, | 2345 | intel_sdvo_set_colorimetry(intel_encoder, |
2341 | SDVO_COLORIMETRY_RGB256); | 2346 | SDVO_COLORIMETRY_RGB256); |
2342 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2347 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2343 | intel_output->clone_mask = | 2348 | intel_encoder->clone_mask = |
2344 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2349 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2345 | (1 << INTEL_ANALOG_CLONE_BIT); | 2350 | (1 << INTEL_ANALOG_CLONE_BIT); |
2346 | } | 2351 | } |
@@ -2351,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2351 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2356 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
2352 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2357 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
2353 | sdvo_priv->is_tv = true; | 2358 | sdvo_priv->is_tv = true; |
2354 | intel_output->needs_tv_clock = true; | 2359 | intel_encoder->needs_tv_clock = true; |
2355 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2360 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2356 | } else if (flags & SDVO_OUTPUT_RGB0) { | 2361 | } else if (flags & SDVO_OUTPUT_RGB0) { |
2357 | 2362 | ||
2358 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | 2363 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; |
2359 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2364 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
2360 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2365 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2361 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2366 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2362 | (1 << INTEL_ANALOG_CLONE_BIT); | 2367 | (1 << INTEL_ANALOG_CLONE_BIT); |
2363 | } else if (flags & SDVO_OUTPUT_RGB1) { | 2368 | } else if (flags & SDVO_OUTPUT_RGB1) { |
2364 | 2369 | ||
2365 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | 2370 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; |
2366 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2371 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
2367 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2372 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2368 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2373 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2369 | (1 << INTEL_ANALOG_CLONE_BIT); | 2374 | (1 << INTEL_ANALOG_CLONE_BIT); |
2370 | } else if (flags & SDVO_OUTPUT_CVBS0) { | 2375 | } else if (flags & SDVO_OUTPUT_CVBS0) { |
2371 | 2376 | ||
@@ -2373,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2373 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2378 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
2374 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2379 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
2375 | sdvo_priv->is_tv = true; | 2380 | sdvo_priv->is_tv = true; |
2376 | intel_output->needs_tv_clock = true; | 2381 | intel_encoder->needs_tv_clock = true; |
2377 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2382 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2378 | } else if (flags & SDVO_OUTPUT_LVDS0) { | 2383 | } else if (flags & SDVO_OUTPUT_LVDS0) { |
2379 | 2384 | ||
2380 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | 2385 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; |
2381 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2386 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
2382 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2387 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
2383 | sdvo_priv->is_lvds = true; | 2388 | sdvo_priv->is_lvds = true; |
2384 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2389 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | |
2385 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2390 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); |
2386 | } else if (flags & SDVO_OUTPUT_LVDS1) { | 2391 | } else if (flags & SDVO_OUTPUT_LVDS1) { |
2387 | 2392 | ||
@@ -2389,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2389 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2394 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
2390 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2395 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
2391 | sdvo_priv->is_lvds = true; | 2396 | sdvo_priv->is_lvds = true; |
2392 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2397 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | |
2393 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2398 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); |
2394 | } else { | 2399 | } else { |
2395 | 2400 | ||
@@ -2402,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2402 | bytes[0], bytes[1]); | 2407 | bytes[0], bytes[1]); |
2403 | ret = false; | 2408 | ret = false; |
2404 | } | 2409 | } |
2405 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 2410 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
2406 | 2411 | ||
2407 | if (ret && registered) | 2412 | if (ret && registered) |
2408 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | 2413 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; |
@@ -2414,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2414 | 2419 | ||
2415 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) | 2420 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) |
2416 | { | 2421 | { |
2417 | struct intel_output *intel_output = to_intel_output(connector); | 2422 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
2418 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 2423 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2419 | struct intel_sdvo_tv_format format; | 2424 | struct intel_sdvo_tv_format format; |
2420 | uint32_t format_map, i; | 2425 | uint32_t format_map, i; |
2421 | uint8_t status; | 2426 | uint8_t status; |
2422 | 2427 | ||
2423 | intel_sdvo_set_target_output(intel_output, | 2428 | intel_sdvo_set_target_output(intel_encoder, |
2424 | sdvo_priv->controlled_output); | 2429 | sdvo_priv->controlled_output); |
2425 | 2430 | ||
2426 | intel_sdvo_write_cmd(intel_output, | 2431 | intel_sdvo_write_cmd(intel_encoder, |
2427 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2432 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); |
2428 | status = intel_sdvo_read_response(intel_output, | 2433 | status = intel_sdvo_read_response(intel_encoder, |
2429 | &format, sizeof(format)); | 2434 | &format, sizeof(format)); |
2430 | if (status != SDVO_CMD_STATUS_SUCCESS) | 2435 | if (status != SDVO_CMD_STATUS_SUCCESS) |
2431 | return; | 2436 | return; |
@@ -2463,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector) | |||
2463 | 2468 | ||
2464 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2469 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) |
2465 | { | 2470 | { |
2466 | struct intel_output *intel_output = to_intel_output(connector); | 2471 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
2467 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 2472 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; |
2468 | struct intel_sdvo_enhancements_reply sdvo_data; | 2473 | struct intel_sdvo_enhancements_reply sdvo_data; |
2469 | struct drm_device *dev = connector->dev; | 2474 | struct drm_device *dev = connector->dev; |
2470 | uint8_t status; | 2475 | uint8_t status; |
2471 | uint16_t response, data_value[2]; | 2476 | uint16_t response, data_value[2]; |
2472 | 2477 | ||
2473 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2478 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2474 | NULL, 0); | 2479 | NULL, 0); |
2475 | status = intel_sdvo_read_response(intel_output, &sdvo_data, | 2480 | status = intel_sdvo_read_response(intel_encoder, &sdvo_data, |
2476 | sizeof(sdvo_data)); | 2481 | sizeof(sdvo_data)); |
2477 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2482 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2478 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | 2483 | DRM_DEBUG_KMS(" incorrect response is returned\n"); |
@@ -2488,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2488 | * property | 2493 | * property |
2489 | */ | 2494 | */ |
2490 | if (sdvo_data.overscan_h) { | 2495 | if (sdvo_data.overscan_h) { |
2491 | intel_sdvo_write_cmd(intel_output, | 2496 | intel_sdvo_write_cmd(intel_encoder, |
2492 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2497 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); |
2493 | status = intel_sdvo_read_response(intel_output, | 2498 | status = intel_sdvo_read_response(intel_encoder, |
2494 | &data_value, 4); | 2499 | &data_value, 4); |
2495 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2500 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2496 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2501 | DRM_DEBUG_KMS("Incorrect SDVO max " |
2497 | "h_overscan\n"); | 2502 | "h_overscan\n"); |
2498 | return; | 2503 | return; |
2499 | } | 2504 | } |
2500 | intel_sdvo_write_cmd(intel_output, | 2505 | intel_sdvo_write_cmd(intel_encoder, |
2501 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | 2506 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); |
2502 | status = intel_sdvo_read_response(intel_output, | 2507 | status = intel_sdvo_read_response(intel_encoder, |
2503 | &response, 2); | 2508 | &response, 2); |
2504 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2509 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2505 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | 2510 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); |
@@ -2529,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2529 | data_value[0], data_value[1], response); | 2534 | data_value[0], data_value[1], response); |
2530 | } | 2535 | } |
2531 | if (sdvo_data.overscan_v) { | 2536 | if (sdvo_data.overscan_v) { |
2532 | intel_sdvo_write_cmd(intel_output, | 2537 | intel_sdvo_write_cmd(intel_encoder, |
2533 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | 2538 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); |
2534 | status = intel_sdvo_read_response(intel_output, | 2539 | status = intel_sdvo_read_response(intel_encoder, |
2535 | &data_value, 4); | 2540 | &data_value, 4); |
2536 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2541 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2537 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2542 | DRM_DEBUG_KMS("Incorrect SDVO max " |
2538 | "v_overscan\n"); | 2543 | "v_overscan\n"); |
2539 | return; | 2544 | return; |
2540 | } | 2545 | } |
2541 | intel_sdvo_write_cmd(intel_output, | 2546 | intel_sdvo_write_cmd(intel_encoder, |
2542 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | 2547 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); |
2543 | status = intel_sdvo_read_response(intel_output, | 2548 | status = intel_sdvo_read_response(intel_encoder, |
2544 | &response, 2); | 2549 | &response, 2); |
2545 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2550 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2546 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | 2551 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); |
@@ -2570,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2570 | data_value[0], data_value[1], response); | 2575 | data_value[0], data_value[1], response); |
2571 | } | 2576 | } |
2572 | if (sdvo_data.position_h) { | 2577 | if (sdvo_data.position_h) { |
2573 | intel_sdvo_write_cmd(intel_output, | 2578 | intel_sdvo_write_cmd(intel_encoder, |
2574 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | 2579 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); |
2575 | status = intel_sdvo_read_response(intel_output, | 2580 | status = intel_sdvo_read_response(intel_encoder, |
2576 | &data_value, 4); | 2581 | &data_value, 4); |
2577 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2582 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2578 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | 2583 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); |
2579 | return; | 2584 | return; |
2580 | } | 2585 | } |
2581 | intel_sdvo_write_cmd(intel_output, | 2586 | intel_sdvo_write_cmd(intel_encoder, |
2582 | SDVO_CMD_GET_POSITION_H, NULL, 0); | 2587 | SDVO_CMD_GET_POSITION_H, NULL, 0); |
2583 | status = intel_sdvo_read_response(intel_output, | 2588 | status = intel_sdvo_read_response(intel_encoder, |
2584 | &response, 2); | 2589 | &response, 2); |
2585 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2590 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2586 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | 2591 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); |
@@ -2601,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2601 | data_value[0], data_value[1], response); | 2606 | data_value[0], data_value[1], response); |
2602 | } | 2607 | } |
2603 | if (sdvo_data.position_v) { | 2608 | if (sdvo_data.position_v) { |
2604 | intel_sdvo_write_cmd(intel_output, | 2609 | intel_sdvo_write_cmd(intel_encoder, |
2605 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | 2610 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); |
2606 | status = intel_sdvo_read_response(intel_output, | 2611 | status = intel_sdvo_read_response(intel_encoder, |
2607 | &data_value, 4); | 2612 | &data_value, 4); |
2608 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2613 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2609 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | 2614 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); |
2610 | return; | 2615 | return; |
2611 | } | 2616 | } |
2612 | intel_sdvo_write_cmd(intel_output, | 2617 | intel_sdvo_write_cmd(intel_encoder, |
2613 | SDVO_CMD_GET_POSITION_V, NULL, 0); | 2618 | SDVO_CMD_GET_POSITION_V, NULL, 0); |
2614 | status = intel_sdvo_read_response(intel_output, | 2619 | status = intel_sdvo_read_response(intel_encoder, |
2615 | &response, 2); | 2620 | &response, 2); |
2616 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2621 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2617 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | 2622 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); |
@@ -2634,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2634 | } | 2639 | } |
2635 | if (sdvo_priv->is_tv) { | 2640 | if (sdvo_priv->is_tv) { |
2636 | if (sdvo_data.saturation) { | 2641 | if (sdvo_data.saturation) { |
2637 | intel_sdvo_write_cmd(intel_output, | 2642 | intel_sdvo_write_cmd(intel_encoder, |
2638 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | 2643 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); |
2639 | status = intel_sdvo_read_response(intel_output, | 2644 | status = intel_sdvo_read_response(intel_encoder, |
2640 | &data_value, 4); | 2645 | &data_value, 4); |
2641 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2646 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2642 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | 2647 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); |
2643 | return; | 2648 | return; |
2644 | } | 2649 | } |
2645 | intel_sdvo_write_cmd(intel_output, | 2650 | intel_sdvo_write_cmd(intel_encoder, |
2646 | SDVO_CMD_GET_SATURATION, NULL, 0); | 2651 | SDVO_CMD_GET_SATURATION, NULL, 0); |
2647 | status = intel_sdvo_read_response(intel_output, | 2652 | status = intel_sdvo_read_response(intel_encoder, |
2648 | &response, 2); | 2653 | &response, 2); |
2649 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2654 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2650 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | 2655 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); |
@@ -2666,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2666 | data_value[0], data_value[1], response); | 2671 | data_value[0], data_value[1], response); |
2667 | } | 2672 | } |
2668 | if (sdvo_data.contrast) { | 2673 | if (sdvo_data.contrast) { |
2669 | intel_sdvo_write_cmd(intel_output, | 2674 | intel_sdvo_write_cmd(intel_encoder, |
2670 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | 2675 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); |
2671 | status = intel_sdvo_read_response(intel_output, | 2676 | status = intel_sdvo_read_response(intel_encoder, |
2672 | &data_value, 4); | 2677 | &data_value, 4); |
2673 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2678 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2674 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | 2679 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); |
2675 | return; | 2680 | return; |
2676 | } | 2681 | } |
2677 | intel_sdvo_write_cmd(intel_output, | 2682 | intel_sdvo_write_cmd(intel_encoder, |
2678 | SDVO_CMD_GET_CONTRAST, NULL, 0); | 2683 | SDVO_CMD_GET_CONTRAST, NULL, 0); |
2679 | status = intel_sdvo_read_response(intel_output, | 2684 | status = intel_sdvo_read_response(intel_encoder, |
2680 | &response, 2); | 2685 | &response, 2); |
2681 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2686 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2682 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | 2687 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); |
@@ -2697,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2697 | data_value[0], data_value[1], response); | 2702 | data_value[0], data_value[1], response); |
2698 | } | 2703 | } |
2699 | if (sdvo_data.hue) { | 2704 | if (sdvo_data.hue) { |
2700 | intel_sdvo_write_cmd(intel_output, | 2705 | intel_sdvo_write_cmd(intel_encoder, |
2701 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | 2706 | SDVO_CMD_GET_MAX_HUE, NULL, 0); |
2702 | status = intel_sdvo_read_response(intel_output, | 2707 | status = intel_sdvo_read_response(intel_encoder, |
2703 | &data_value, 4); | 2708 | &data_value, 4); |
2704 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2709 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2705 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | 2710 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); |
2706 | return; | 2711 | return; |
2707 | } | 2712 | } |
2708 | intel_sdvo_write_cmd(intel_output, | 2713 | intel_sdvo_write_cmd(intel_encoder, |
2709 | SDVO_CMD_GET_HUE, NULL, 0); | 2714 | SDVO_CMD_GET_HUE, NULL, 0); |
2710 | status = intel_sdvo_read_response(intel_output, | 2715 | status = intel_sdvo_read_response(intel_encoder, |
2711 | &response, 2); | 2716 | &response, 2); |
2712 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2717 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2713 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | 2718 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); |
@@ -2730,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2730 | } | 2735 | } |
2731 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 2736 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
2732 | if (sdvo_data.brightness) { | 2737 | if (sdvo_data.brightness) { |
2733 | intel_sdvo_write_cmd(intel_output, | 2738 | intel_sdvo_write_cmd(intel_encoder, |
2734 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2739 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); |
2735 | status = intel_sdvo_read_response(intel_output, | 2740 | status = intel_sdvo_read_response(intel_encoder, |
2736 | &data_value, 4); | 2741 | &data_value, 4); |
2737 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2742 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2738 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2743 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); |
2739 | return; | 2744 | return; |
2740 | } | 2745 | } |
2741 | intel_sdvo_write_cmd(intel_output, | 2746 | intel_sdvo_write_cmd(intel_encoder, |
2742 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | 2747 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); |
2743 | status = intel_sdvo_read_response(intel_output, | 2748 | status = intel_sdvo_read_response(intel_encoder, |
2744 | &response, 2); | 2749 | &response, 2); |
2745 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2750 | if (status != SDVO_CMD_STATUS_SUCCESS) { |
2746 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | 2751 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); |
@@ -2765,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2765 | return; | 2770 | return; |
2766 | } | 2771 | } |
2767 | 2772 | ||
2768 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2773 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2769 | { | 2774 | { |
2770 | struct drm_i915_private *dev_priv = dev->dev_private; | 2775 | struct drm_i915_private *dev_priv = dev->dev_private; |
2771 | struct drm_connector *connector; | 2776 | struct drm_connector *connector; |
2772 | struct intel_output *intel_output; | 2777 | struct intel_encoder *intel_encoder; |
2773 | struct intel_sdvo_priv *sdvo_priv; | 2778 | struct intel_sdvo_priv *sdvo_priv; |
2774 | 2779 | ||
2775 | u8 ch[0x40]; | 2780 | u8 ch[0x40]; |
2776 | int i; | 2781 | int i; |
2777 | 2782 | ||
2778 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2783 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
2779 | if (!intel_output) { | 2784 | if (!intel_encoder) { |
2780 | return false; | 2785 | return false; |
2781 | } | 2786 | } |
2782 | 2787 | ||
2783 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 2788 | sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); |
2784 | sdvo_priv->output_device = output_device; | 2789 | sdvo_priv->sdvo_reg = sdvo_reg; |
2785 | 2790 | ||
2786 | intel_output->dev_priv = sdvo_priv; | 2791 | intel_encoder->dev_priv = sdvo_priv; |
2787 | intel_output->type = INTEL_OUTPUT_SDVO; | 2792 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2788 | 2793 | ||
2789 | /* setup the DDC bus. */ | 2794 | /* setup the DDC bus. */ |
2790 | if (output_device == SDVOB) | 2795 | if (sdvo_reg == SDVOB) |
2791 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 2796 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
2792 | else | 2797 | else |
2793 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 2798 | intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
2794 | 2799 | ||
2795 | if (!intel_output->i2c_bus) | 2800 | if (!intel_encoder->i2c_bus) |
2796 | goto err_inteloutput; | 2801 | goto err_inteloutput; |
2797 | 2802 | ||
2798 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); | 2803 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
2799 | 2804 | ||
2800 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | 2805 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
2801 | intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; | 2806 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; |
2802 | 2807 | ||
2803 | /* Read the regs to test if we can talk to the device */ | 2808 | /* Read the regs to test if we can talk to the device */ |
2804 | for (i = 0; i < 0x40; i++) { | 2809 | for (i = 0; i < 0x40; i++) { |
2805 | if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { | 2810 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { |
2806 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2811 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2807 | output_device == SDVOB ? 'B' : 'C'); | 2812 | sdvo_reg == SDVOB ? 'B' : 'C'); |
2808 | goto err_i2c; | 2813 | goto err_i2c; |
2809 | } | 2814 | } |
2810 | } | 2815 | } |
2811 | 2816 | ||
2812 | /* setup the DDC bus. */ | 2817 | /* setup the DDC bus. */ |
2813 | if (output_device == SDVOB) { | 2818 | if (sdvo_reg == SDVOB) { |
2814 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
2815 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2816 | "SDVOB/VGA DDC BUS"); | 2821 | "SDVOB/VGA DDC BUS"); |
2817 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2822 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2818 | } else { | 2823 | } else { |
2819 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2824 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | 2825 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2821 | "SDVOC/VGA DDC BUS"); | 2826 | "SDVOC/VGA DDC BUS"); |
2822 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2827 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2823 | } | 2828 | } |
2824 | 2829 | ||
2825 | if (intel_output->ddc_bus == NULL) | 2830 | if (intel_encoder->ddc_bus == NULL) |
2826 | goto err_i2c; | 2831 | goto err_i2c; |
2827 | 2832 | ||
2828 | /* Wrap with our custom algo which switches to DDC mode */ | 2833 | /* Wrap with our custom algo which switches to DDC mode */ |
2829 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2834 | intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
2830 | 2835 | ||
2831 | /* In default case sdvo lvds is false */ | 2836 | /* In default case sdvo lvds is false */ |
2832 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 2837 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); |
2833 | 2838 | ||
2834 | if (intel_sdvo_output_setup(intel_output, | 2839 | if (intel_sdvo_output_setup(intel_encoder, |
2835 | sdvo_priv->caps.output_flags) != true) { | 2840 | sdvo_priv->caps.output_flags) != true) { |
2836 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2841 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2837 | output_device == SDVOB ? 'B' : 'C'); | 2842 | sdvo_reg == SDVOB ? 'B' : 'C'); |
2838 | goto err_i2c; | 2843 | goto err_i2c; |
2839 | } | 2844 | } |
2840 | 2845 | ||
2841 | 2846 | ||
2842 | connector = &intel_output->base; | 2847 | connector = &intel_encoder->base; |
2843 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | 2848 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, |
2844 | connector->connector_type); | 2849 | connector->connector_type); |
2845 | 2850 | ||
@@ -2848,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2848 | connector->doublescan_allowed = 0; | 2853 | connector->doublescan_allowed = 0; |
2849 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 2854 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
2850 | 2855 | ||
2851 | drm_encoder_init(dev, &intel_output->enc, | 2856 | drm_encoder_init(dev, &intel_encoder->enc, |
2852 | &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); | 2857 | &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); |
2853 | 2858 | ||
2854 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2859 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
2855 | 2860 | ||
2856 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2861 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); |
2857 | if (sdvo_priv->is_tv) | 2862 | if (sdvo_priv->is_tv) |
2858 | intel_sdvo_tv_create_property(connector); | 2863 | intel_sdvo_tv_create_property(connector); |
2859 | 2864 | ||
@@ -2865,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2865 | intel_sdvo_select_ddc_bus(sdvo_priv); | 2870 | intel_sdvo_select_ddc_bus(sdvo_priv); |
2866 | 2871 | ||
2867 | /* Set the input timing to the screen. Assume always input 0. */ | 2872 | /* Set the input timing to the screen. Assume always input 0. */ |
2868 | intel_sdvo_set_target_input(intel_output, true, false); | 2873 | intel_sdvo_set_target_input(intel_encoder, true, false); |
2869 | 2874 | ||
2870 | intel_sdvo_get_input_pixel_clock_range(intel_output, | 2875 | intel_sdvo_get_input_pixel_clock_range(intel_encoder, |
2871 | &sdvo_priv->pixel_clock_min, | 2876 | &sdvo_priv->pixel_clock_min, |
2872 | &sdvo_priv->pixel_clock_max); | 2877 | &sdvo_priv->pixel_clock_max); |
2873 | 2878 | ||
@@ -2894,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2894 | err_i2c: | 2899 | err_i2c: |
2895 | if (sdvo_priv->analog_ddc_bus != NULL) | 2900 | if (sdvo_priv->analog_ddc_bus != NULL) |
2896 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 2901 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); |
2897 | if (intel_output->ddc_bus != NULL) | 2902 | if (intel_encoder->ddc_bus != NULL) |
2898 | intel_i2c_destroy(intel_output->ddc_bus); | 2903 | intel_i2c_destroy(intel_encoder->ddc_bus); |
2899 | if (intel_output->i2c_bus != NULL) | 2904 | if (intel_encoder->i2c_bus != NULL) |
2900 | intel_i2c_destroy(intel_output->i2c_bus); | 2905 | intel_i2c_destroy(intel_encoder->i2c_bus); |
2901 | err_inteloutput: | 2906 | err_inteloutput: |
2902 | kfree(intel_output); | 2907 | kfree(intel_encoder); |
2903 | 2908 | ||
2904 | return false; | 2909 | return false; |
2905 | } | 2910 | } |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec110b741..d7d39b2327df 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector) | |||
921 | { | 921 | { |
922 | struct drm_device *dev = connector->dev; | 922 | struct drm_device *dev = connector->dev; |
923 | struct drm_i915_private *dev_priv = dev->dev_private; | 923 | struct drm_i915_private *dev_priv = dev->dev_private; |
924 | struct intel_output *intel_output = to_intel_output(connector); | 924 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
925 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 925 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
926 | int i; | 926 | int i; |
927 | 927 | ||
928 | tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); | 928 | tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); |
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector) | |||
971 | { | 971 | { |
972 | struct drm_device *dev = connector->dev; | 972 | struct drm_device *dev = connector->dev; |
973 | struct drm_i915_private *dev_priv = dev->dev_private; | 973 | struct drm_i915_private *dev_priv = dev->dev_private; |
974 | struct intel_output *intel_output = to_intel_output(connector); | 974 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
975 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 975 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
976 | struct drm_crtc *crtc = connector->encoder->crtc; | 976 | struct drm_crtc *crtc = connector->encoder->crtc; |
977 | struct intel_crtc *intel_crtc; | 977 | struct intel_crtc *intel_crtc; |
978 | int i; | 978 | int i; |
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format) | |||
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | static const struct tv_mode * | 1070 | static const struct tv_mode * |
1071 | intel_tv_mode_find (struct intel_output *intel_output) | 1071 | intel_tv_mode_find (struct intel_encoder *intel_encoder) |
1072 | { | 1072 | { |
1073 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 1073 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1074 | 1074 | ||
1075 | return intel_tv_mode_lookup(tv_priv->tv_format); | 1075 | return intel_tv_mode_lookup(tv_priv->tv_format); |
1076 | } | 1076 | } |
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output) | |||
1078 | static enum drm_mode_status | 1078 | static enum drm_mode_status |
1079 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 1079 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
1080 | { | 1080 | { |
1081 | struct intel_output *intel_output = to_intel_output(connector); | 1081 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1082 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1082 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1083 | 1083 | ||
1084 | /* Ensure TV refresh is close to desired refresh */ | 1084 | /* Ensure TV refresh is close to desired refresh */ |
1085 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 1085 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1095 | { | 1095 | { |
1096 | struct drm_device *dev = encoder->dev; | 1096 | struct drm_device *dev = encoder->dev; |
1097 | struct drm_mode_config *drm_config = &dev->mode_config; | 1097 | struct drm_mode_config *drm_config = &dev->mode_config; |
1098 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 1098 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1099 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); | 1099 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); |
1100 | struct drm_encoder *other_encoder; | 1100 | struct drm_encoder *other_encoder; |
1101 | 1101 | ||
1102 | if (!tv_mode) | 1102 | if (!tv_mode) |
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1121 | struct drm_i915_private *dev_priv = dev->dev_private; | 1121 | struct drm_i915_private *dev_priv = dev->dev_private; |
1122 | struct drm_crtc *crtc = encoder->crtc; | 1122 | struct drm_crtc *crtc = encoder->crtc; |
1123 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1123 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1124 | struct intel_output *intel_output = enc_to_intel_output(encoder); | 1124 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); |
1125 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 1125 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1126 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1126 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1127 | u32 tv_ctl; | 1127 | u32 tv_ctl; |
1128 | u32 hctl1, hctl2, hctl3; | 1128 | u32 hctl1, hctl2, hctl3; |
1129 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 1129 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = { | |||
1360 | * \return false if TV is disconnected. | 1360 | * \return false if TV is disconnected. |
1361 | */ | 1361 | */ |
1362 | static int | 1362 | static int |
1363 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) | 1363 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) |
1364 | { | 1364 | { |
1365 | struct drm_encoder *encoder = &intel_output->enc; | 1365 | struct drm_encoder *encoder = &intel_encoder->enc; |
1366 | struct drm_device *dev = encoder->dev; | 1366 | struct drm_device *dev = encoder->dev; |
1367 | struct drm_i915_private *dev_priv = dev->dev_private; | 1367 | struct drm_i915_private *dev_priv = dev->dev_private; |
1368 | unsigned long irqflags; | 1368 | unsigned long irqflags; |
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) | |||
1441 | */ | 1441 | */ |
1442 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1442 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1443 | { | 1443 | { |
1444 | struct intel_output *intel_output = to_intel_output(connector); | 1444 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1445 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 1445 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1446 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1446 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1447 | int i; | 1447 | int i; |
1448 | 1448 | ||
1449 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1449 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == |
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector) | |||
1475 | { | 1475 | { |
1476 | struct drm_crtc *crtc; | 1476 | struct drm_crtc *crtc; |
1477 | struct drm_display_mode mode; | 1477 | struct drm_display_mode mode; |
1478 | struct intel_output *intel_output = to_intel_output(connector); | 1478 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1479 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 1479 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1480 | struct drm_encoder *encoder = &intel_output->enc; | 1480 | struct drm_encoder *encoder = &intel_encoder->enc; |
1481 | int dpms_mode; | 1481 | int dpms_mode; |
1482 | int type = tv_priv->type; | 1482 | int type = tv_priv->type; |
1483 | 1483 | ||
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector) | |||
1485 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1485 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1486 | 1486 | ||
1487 | if (encoder->crtc && encoder->crtc->enabled) { | 1487 | if (encoder->crtc && encoder->crtc->enabled) { |
1488 | type = intel_tv_detect_type(encoder->crtc, intel_output); | 1488 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); |
1489 | } else { | 1489 | } else { |
1490 | crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); | 1490 | crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode); |
1491 | if (crtc) { | 1491 | if (crtc) { |
1492 | type = intel_tv_detect_type(crtc, intel_output); | 1492 | type = intel_tv_detect_type(crtc, intel_encoder); |
1493 | intel_release_load_detect_pipe(intel_output, dpms_mode); | 1493 | intel_release_load_detect_pipe(intel_encoder, dpms_mode); |
1494 | } else | 1494 | } else |
1495 | type = -1; | 1495 | type = -1; |
1496 | } | 1496 | } |
@@ -1525,8 +1525,8 @@ static void | |||
1525 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | 1525 | intel_tv_chose_preferred_modes(struct drm_connector *connector, |
1526 | struct drm_display_mode *mode_ptr) | 1526 | struct drm_display_mode *mode_ptr) |
1527 | { | 1527 | { |
1528 | struct intel_output *intel_output = to_intel_output(connector); | 1528 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1529 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1529 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1530 | 1530 | ||
1531 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1531 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
1532 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1532 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
@@ -1550,8 +1550,8 @@ static int | |||
1550 | intel_tv_get_modes(struct drm_connector *connector) | 1550 | intel_tv_get_modes(struct drm_connector *connector) |
1551 | { | 1551 | { |
1552 | struct drm_display_mode *mode_ptr; | 1552 | struct drm_display_mode *mode_ptr; |
1553 | struct intel_output *intel_output = to_intel_output(connector); | 1553 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1554 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); | 1554 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); |
1555 | int j, count = 0; | 1555 | int j, count = 0; |
1556 | u64 tmp; | 1556 | u64 tmp; |
1557 | 1557 | ||
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1604 | static void | 1604 | static void |
1605 | intel_tv_destroy (struct drm_connector *connector) | 1605 | intel_tv_destroy (struct drm_connector *connector) |
1606 | { | 1606 | { |
1607 | struct intel_output *intel_output = to_intel_output(connector); | 1607 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1608 | 1608 | ||
1609 | drm_sysfs_connector_remove(connector); | 1609 | drm_sysfs_connector_remove(connector); |
1610 | drm_connector_cleanup(connector); | 1610 | drm_connector_cleanup(connector); |
1611 | kfree(intel_output); | 1611 | kfree(intel_encoder); |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | 1614 | ||
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1617 | uint64_t val) | 1617 | uint64_t val) |
1618 | { | 1618 | { |
1619 | struct drm_device *dev = connector->dev; | 1619 | struct drm_device *dev = connector->dev; |
1620 | struct intel_output *intel_output = to_intel_output(connector); | 1620 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); |
1621 | struct intel_tv_priv *tv_priv = intel_output->dev_priv; | 1621 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; |
1622 | struct drm_encoder *encoder = &intel_output->enc; | 1622 | struct drm_encoder *encoder = &intel_encoder->enc; |
1623 | struct drm_crtc *crtc = encoder->crtc; | 1623 | struct drm_crtc *crtc = encoder->crtc; |
1624 | int ret = 0; | 1624 | int ret = 0; |
1625 | bool changed = false; | 1625 | bool changed = false; |
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev) | |||
1740 | { | 1740 | { |
1741 | struct drm_i915_private *dev_priv = dev->dev_private; | 1741 | struct drm_i915_private *dev_priv = dev->dev_private; |
1742 | struct drm_connector *connector; | 1742 | struct drm_connector *connector; |
1743 | struct intel_output *intel_output; | 1743 | struct intel_encoder *intel_encoder; |
1744 | struct intel_tv_priv *tv_priv; | 1744 | struct intel_tv_priv *tv_priv; |
1745 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1745 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1746 | char **tv_format_names; | 1746 | char **tv_format_names; |
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev) | |||
1780 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1780 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
1781 | return; | 1781 | return; |
1782 | 1782 | ||
1783 | intel_output = kzalloc(sizeof(struct intel_output) + | 1783 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + |
1784 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1784 | sizeof(struct intel_tv_priv), GFP_KERNEL); |
1785 | if (!intel_output) { | 1785 | if (!intel_encoder) { |
1786 | return; | 1786 | return; |
1787 | } | 1787 | } |
1788 | 1788 | ||
1789 | connector = &intel_output->base; | 1789 | connector = &intel_encoder->base; |
1790 | 1790 | ||
1791 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1791 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1792 | DRM_MODE_CONNECTOR_SVIDEO); | 1792 | DRM_MODE_CONNECTOR_SVIDEO); |
1793 | 1793 | ||
1794 | drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, | 1794 | drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, |
1795 | DRM_MODE_ENCODER_TVDAC); | 1795 | DRM_MODE_ENCODER_TVDAC); |
1796 | 1796 | ||
1797 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 1797 | drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); |
1798 | tv_priv = (struct intel_tv_priv *)(intel_output + 1); | 1798 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); |
1799 | intel_output->type = INTEL_OUTPUT_TVOUT; | 1799 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1800 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | 1800 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1801 | intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1801 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1802 | intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1802 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1803 | intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1803 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1804 | intel_output->dev_priv = tv_priv; | 1804 | intel_encoder->dev_priv = tv_priv; |
1805 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | 1805 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; |
1806 | 1806 | ||
1807 | /* BIOS margin values */ | 1807 | /* BIOS margin values */ |
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev) | |||
1812 | 1812 | ||
1813 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1813 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
1814 | 1814 | ||
1815 | drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); | 1815 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
1816 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1816 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
1817 | connector->interlace_allowed = false; | 1817 | connector->interlace_allowed = false; |
1818 | connector->doublescan_allowed = false; | 1818 | connector->doublescan_allowed = false; |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 7f0d807a0d0d..453df3f6053f 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ | 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ |
23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ | 23 | nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ |
24 | nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ | 24 | nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ |
25 | nv17_gpio.o | 25 | nv17_gpio.o nv50_gpio.o |
26 | 26 | ||
27 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o | 27 | nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o |
28 | nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o | 28 | nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b5a9336a2e88..abc382a9918b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -2573,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2573 | * each GPIO according to various values listed in each entry | 2573 | * each GPIO according to various values listed in each entry |
2574 | */ | 2574 | */ |
2575 | 2575 | ||
2576 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | 2576 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
2577 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | 2577 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; |
2578 | const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr]; | ||
2579 | const uint8_t *gpio_entry; | ||
2580 | int i; | 2578 | int i; |
2581 | 2579 | ||
2582 | if (!iexec->execute) | 2580 | if (dev_priv->card_type != NV_50) { |
2583 | return 1; | 2581 | NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); |
2584 | 2582 | return -ENODEV; | |
2585 | if (bios->dcb.version != 0x40) { | ||
2586 | NV_ERROR(bios->dev, "DCB table not version 4.0\n"); | ||
2587 | return 0; | ||
2588 | } | ||
2589 | |||
2590 | if (!bios->dcb.gpio_table_ptr) { | ||
2591 | NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); | ||
2592 | return 0; | ||
2593 | } | 2583 | } |
2594 | 2584 | ||
2595 | gpio_entry = gpio_table + gpio_table[1]; | 2585 | if (!iexec->execute) |
2596 | for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) { | 2586 | return 1; |
2597 | uint32_t entry = ROM32(gpio_entry[0]), r, s, v; | ||
2598 | int line = (entry & 0x0000001f); | ||
2599 | 2587 | ||
2600 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry); | 2588 | for (i = 0; i < bios->dcb.gpio.entries; i++) { |
2589 | struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i]; | ||
2590 | uint32_t r, s, v; | ||
2601 | 2591 | ||
2602 | if ((entry & 0x0000ff00) == 0x0000ff00) | 2592 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); |
2603 | continue; | ||
2604 | 2593 | ||
2605 | r = nv50_gpio_reg[line >> 3]; | 2594 | nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); |
2606 | s = (line & 0x07) << 2; | ||
2607 | v = bios_rd32(bios, r) & ~(0x00000003 << s); | ||
2608 | if (entry & 0x01000000) | ||
2609 | v |= (((entry & 0x60000000) >> 29) ^ 2) << s; | ||
2610 | else | ||
2611 | v |= (((entry & 0x18000000) >> 27) ^ 2) << s; | ||
2612 | bios_wr32(bios, r, v); | ||
2613 | 2595 | ||
2614 | r = nv50_gpio_ctl[line >> 4]; | 2596 | /* The NVIDIA binary driver doesn't appear to actually do |
2615 | s = (line & 0x0f); | 2597 | * any of this, my VBIOS does however. |
2598 | */ | ||
2599 | /* Not a clue, needs de-magicing */ | ||
2600 | r = nv50_gpio_ctl[gpio->line >> 4]; | ||
2601 | s = (gpio->line & 0x0f); | ||
2616 | v = bios_rd32(bios, r) & ~(0x00010001 << s); | 2602 | v = bios_rd32(bios, r) & ~(0x00010001 << s); |
2617 | switch ((entry & 0x06000000) >> 25) { | 2603 | switch ((gpio->entry & 0x06000000) >> 25) { |
2618 | case 1: | 2604 | case 1: |
2619 | v |= (0x00000001 << s); | 2605 | v |= (0x00000001 << s); |
2620 | break; | 2606 | break; |
@@ -3198,7 +3184,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int | |||
3198 | struct nvbios *bios = &dev_priv->vbios; | 3184 | struct nvbios *bios = &dev_priv->vbios; |
3199 | unsigned int outputset = (dcbent->or == 4) ? 1 : 0; | 3185 | unsigned int outputset = (dcbent->or == 4) ? 1 : 0; |
3200 | uint16_t scriptptr = 0, clktable; | 3186 | uint16_t scriptptr = 0, clktable; |
3201 | uint8_t clktableptr = 0; | ||
3202 | 3187 | ||
3203 | /* | 3188 | /* |
3204 | * For now we assume version 3.0 table - g80 support will need some | 3189 | * For now we assume version 3.0 table - g80 support will need some |
@@ -3217,26 +3202,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int | |||
3217 | scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); | 3202 | scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]); |
3218 | break; | 3203 | break; |
3219 | case LVDS_RESET: | 3204 | case LVDS_RESET: |
3205 | clktable = bios->fp.lvdsmanufacturerpointer + 15; | ||
3206 | if (dcbent->or == 4) | ||
3207 | clktable += 8; | ||
3208 | |||
3220 | if (dcbent->lvdsconf.use_straps_for_mode) { | 3209 | if (dcbent->lvdsconf.use_straps_for_mode) { |
3221 | if (bios->fp.dual_link) | 3210 | if (bios->fp.dual_link) |
3222 | clktableptr += 2; | 3211 | clktable += 4; |
3223 | if (bios->fp.BITbit1) | 3212 | if (bios->fp.if_is_24bit) |
3224 | clktableptr++; | 3213 | clktable += 2; |
3225 | } else { | 3214 | } else { |
3226 | /* using EDID */ | 3215 | /* using EDID */ |
3227 | uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; | 3216 | int cmpval_24bit = (dcbent->or == 4) ? 4 : 1; |
3228 | int fallbackcmpval = (dcbent->or == 4) ? 4 : 1; | ||
3229 | 3217 | ||
3230 | if (bios->fp.dual_link) { | 3218 | if (bios->fp.dual_link) { |
3231 | clktableptr += 2; | 3219 | clktable += 4; |
3232 | fallbackcmpval *= 2; | 3220 | cmpval_24bit <<= 1; |
3233 | } | 3221 | } |
3234 | if (fallbackcmpval & fallback) | 3222 | |
3235 | clktableptr++; | 3223 | if (bios->fp.strapless_is_24bit & cmpval_24bit) |
3224 | clktable += 2; | ||
3236 | } | 3225 | } |
3237 | 3226 | ||
3238 | /* adding outputset * 8 may not be correct */ | 3227 | clktable = ROM16(bios->data[clktable]); |
3239 | clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]); | ||
3240 | if (!clktable) { | 3228 | if (!clktable) { |
3241 | NV_ERROR(dev, "Pixel clock comparison table not found\n"); | 3229 | NV_ERROR(dev, "Pixel clock comparison table not found\n"); |
3242 | return -ENOENT; | 3230 | return -ENOENT; |
@@ -3638,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
3638 | *if_is_24bit = bios->data[lvdsofs] & 16; | 3626 | *if_is_24bit = bios->data[lvdsofs] & 16; |
3639 | break; | 3627 | break; |
3640 | case 0x30: | 3628 | case 0x30: |
3641 | /* | 3629 | case 0x40: |
3642 | * My money would be on there being a 24 bit interface bit in | ||
3643 | * this table, but I have no example of a laptop bios with a | ||
3644 | * 24 bit panel to confirm that. Hence we shout loudly if any | ||
3645 | * bit other than bit 0 is set (I've not even seen bit 1) | ||
3646 | */ | ||
3647 | if (bios->data[lvdsofs] > 1) | ||
3648 | NV_ERROR(dev, | ||
3649 | "You have a very unusual laptop display; please report it\n"); | ||
3650 | /* | 3630 | /* |
3651 | * No sign of the "power off for reset" or "reset for panel | 3631 | * No sign of the "power off for reset" or "reset for panel |
3652 | * on" bits, but it's safer to assume we should | 3632 | * on" bits, but it's safer to assume we should |
3653 | */ | 3633 | */ |
3654 | bios->fp.power_off_for_reset = true; | 3634 | bios->fp.power_off_for_reset = true; |
3655 | bios->fp.reset_after_pclk_change = true; | 3635 | bios->fp.reset_after_pclk_change = true; |
3636 | |||
3656 | /* | 3637 | /* |
3657 | * It's ok lvdsofs is wrong for nv4x edid case; dual_link is | 3638 | * It's ok lvdsofs is wrong for nv4x edid case; dual_link is |
3658 | * over-written, and BITbit1 isn't used | 3639 | * over-written, and if_is_24bit isn't used |
3659 | */ | 3640 | */ |
3660 | bios->fp.dual_link = bios->data[lvdsofs] & 1; | 3641 | bios->fp.dual_link = bios->data[lvdsofs] & 1; |
3661 | bios->fp.BITbit1 = bios->data[lvdsofs] & 2; | ||
3662 | bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; | ||
3663 | break; | ||
3664 | case 0x40: | ||
3665 | bios->fp.dual_link = bios->data[lvdsofs] & 1; | ||
3666 | bios->fp.if_is_24bit = bios->data[lvdsofs] & 2; | 3642 | bios->fp.if_is_24bit = bios->data[lvdsofs] & 2; |
3667 | bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; | 3643 | bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; |
3668 | bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; | 3644 | bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; |
3669 | break; | 3645 | break; |
3670 | } | 3646 | } |
3671 | 3647 | ||
3648 | /* Dell Latitude D620 reports a too-high value for the dual-link | ||
3649 | * transition freq, causing us to program the panel incorrectly. | ||
3650 | * | ||
3651 | * It doesn't appear the VBIOS actually uses its transition freq | ||
3652 | * (90000kHz), instead it uses the "Number of LVDS channels" field | ||
3653 | * out of the panel ID structure (http://www.spwg.org/). | ||
3654 | * | ||
3655 | * For the moment, a quirk will do :) | ||
3656 | */ | ||
3657 | if ((dev->pdev->device == 0x01d7) && | ||
3658 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
3659 | (dev->pdev->subsystem_device == 0x01c2)) { | ||
3660 | bios->fp.duallink_transition_clk = 80000; | ||
3661 | } | ||
3662 | |||
3672 | /* set dual_link flag for EDID case */ | 3663 | /* set dual_link flag for EDID case */ |
3673 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) | 3664 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) |
3674 | bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk); | 3665 | bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk); |
@@ -5077,25 +5068,25 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset) | |||
5077 | gpio->tag = tag; | 5068 | gpio->tag = tag; |
5078 | gpio->line = line; | 5069 | gpio->line = line; |
5079 | gpio->invert = flags != 4; | 5070 | gpio->invert = flags != 4; |
5071 | gpio->entry = ent; | ||
5080 | } | 5072 | } |
5081 | 5073 | ||
5082 | static void | 5074 | static void |
5083 | parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset) | 5075 | parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset) |
5084 | { | 5076 | { |
5077 | uint32_t entry = ROM32(bios->data[offset]); | ||
5085 | struct dcb_gpio_entry *gpio; | 5078 | struct dcb_gpio_entry *gpio; |
5086 | uint32_t ent = ROM32(bios->data[offset]); | ||
5087 | uint8_t line = ent & 0x1f, | ||
5088 | tag = ent >> 8 & 0xff; | ||
5089 | 5079 | ||
5090 | if (tag == 0xff) | 5080 | if ((entry & 0x0000ff00) == 0x0000ff00) |
5091 | return; | 5081 | return; |
5092 | 5082 | ||
5093 | gpio = new_gpio_entry(bios); | 5083 | gpio = new_gpio_entry(bios); |
5094 | 5084 | gpio->tag = (entry & 0x0000ff00) >> 8; | |
5095 | /* Currently unused, we may need more fields parsed at some | 5085 | gpio->line = (entry & 0x0000001f) >> 0; |
5096 | * point. */ | 5086 | gpio->state_default = (entry & 0x01000000) >> 24; |
5097 | gpio->tag = tag; | 5087 | gpio->state[0] = (entry & 0x18000000) >> 27; |
5098 | gpio->line = line; | 5088 | gpio->state[1] = (entry & 0x60000000) >> 29; |
5089 | gpio->entry = entry; | ||
5099 | } | 5090 | } |
5100 | 5091 | ||
5101 | static void | 5092 | static void |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 4f88e6924d27..c0d7b0a3ece0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -49,6 +49,9 @@ struct dcb_gpio_entry { | |||
49 | enum dcb_gpio_tag tag; | 49 | enum dcb_gpio_tag tag; |
50 | int line; | 50 | int line; |
51 | bool invert; | 51 | bool invert; |
52 | uint32_t entry; | ||
53 | uint8_t state_default; | ||
54 | uint8_t state[2]; | ||
52 | }; | 55 | }; |
53 | 56 | ||
54 | struct dcb_gpio_table { | 57 | struct dcb_gpio_table { |
@@ -267,7 +270,6 @@ struct nvbios { | |||
267 | bool reset_after_pclk_change; | 270 | bool reset_after_pclk_change; |
268 | bool dual_link; | 271 | bool dual_link; |
269 | bool link_c_increment; | 272 | bool link_c_increment; |
270 | bool BITbit1; | ||
271 | bool if_is_24bit; | 273 | bool if_is_24bit; |
272 | int duallink_transition_clk; | 274 | int duallink_transition_clk; |
273 | uint8_t strapless_is_24bit; | 275 | uint8_t strapless_is_24bit; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 9042dd7fb058..957d17629840 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -72,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev, | |||
72 | * many small buffers. | 72 | * many small buffers. |
73 | */ | 73 | */ |
74 | if (dev_priv->card_type == NV_50) { | 74 | if (dev_priv->card_type == NV_50) { |
75 | uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; | 75 | uint32_t block_size = dev_priv->vram_size >> 15; |
76 | int i; | 76 | int i; |
77 | 77 | ||
78 | switch (tile_flags) { | 78 | switch (tile_flags) { |
@@ -154,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
154 | 154 | ||
155 | nvbo->placement.fpfn = 0; | 155 | nvbo->placement.fpfn = 0; |
156 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; | 156 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; |
157 | nouveau_bo_placement_set(nvbo, flags); | 157 | nouveau_bo_placement_set(nvbo, flags, 0); |
158 | 158 | ||
159 | nvbo->channel = chan; | 159 | nvbo->channel = chan; |
160 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, | 160 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, |
@@ -173,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
175 | 175 | ||
176 | static void | ||
177 | set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) | ||
178 | { | ||
179 | *n = 0; | ||
180 | |||
181 | if (type & TTM_PL_FLAG_VRAM) | ||
182 | pl[(*n)++] = TTM_PL_FLAG_VRAM | flags; | ||
183 | if (type & TTM_PL_FLAG_TT) | ||
184 | pl[(*n)++] = TTM_PL_FLAG_TT | flags; | ||
185 | if (type & TTM_PL_FLAG_SYSTEM) | ||
186 | pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; | ||
187 | } | ||
188 | |||
176 | void | 189 | void |
177 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) | 190 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) |
178 | { | 191 | { |
179 | int n = 0; | 192 | struct ttm_placement *pl = &nvbo->placement; |
180 | 193 | uint32_t flags = TTM_PL_MASK_CACHING | | |
181 | if (memtype & TTM_PL_FLAG_VRAM) | 194 | (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0); |
182 | nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; | 195 | |
183 | if (memtype & TTM_PL_FLAG_TT) | 196 | pl->placement = nvbo->placements; |
184 | nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 197 | set_placement_list(nvbo->placements, &pl->num_placement, |
185 | if (memtype & TTM_PL_FLAG_SYSTEM) | 198 | type, flags); |
186 | nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; | 199 | |
187 | nvbo->placement.placement = nvbo->placements; | 200 | pl->busy_placement = nvbo->busy_placements; |
188 | nvbo->placement.busy_placement = nvbo->placements; | 201 | set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, |
189 | nvbo->placement.num_placement = n; | 202 | type | busy, flags); |
190 | nvbo->placement.num_busy_placement = n; | ||
191 | |||
192 | if (nvbo->pin_refcnt) { | ||
193 | while (n--) | ||
194 | nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT; | ||
195 | } | ||
196 | } | 203 | } |
197 | 204 | ||
198 | int | 205 | int |
@@ -200,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
200 | { | 207 | { |
201 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | 208 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); |
202 | struct ttm_buffer_object *bo = &nvbo->bo; | 209 | struct ttm_buffer_object *bo = &nvbo->bo; |
203 | int ret, i; | 210 | int ret; |
204 | 211 | ||
205 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { | 212 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { |
206 | NV_ERROR(nouveau_bdev(bo->bdev)->dev, | 213 | NV_ERROR(nouveau_bdev(bo->bdev)->dev, |
@@ -216,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
216 | if (ret) | 223 | if (ret) |
217 | goto out; | 224 | goto out; |
218 | 225 | ||
219 | nouveau_bo_placement_set(nvbo, memtype); | 226 | nouveau_bo_placement_set(nvbo, memtype, 0); |
220 | for (i = 0; i < nvbo->placement.num_placement; i++) | ||
221 | nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT; | ||
222 | 227 | ||
223 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); | 228 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); |
224 | if (ret == 0) { | 229 | if (ret == 0) { |
@@ -245,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
245 | { | 250 | { |
246 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | 251 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); |
247 | struct ttm_buffer_object *bo = &nvbo->bo; | 252 | struct ttm_buffer_object *bo = &nvbo->bo; |
248 | int ret, i; | 253 | int ret; |
249 | 254 | ||
250 | if (--nvbo->pin_refcnt) | 255 | if (--nvbo->pin_refcnt) |
251 | return 0; | 256 | return 0; |
@@ -254,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
254 | if (ret) | 259 | if (ret) |
255 | return ret; | 260 | return ret; |
256 | 261 | ||
257 | for (i = 0; i < nvbo->placement.num_placement; i++) | 262 | nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); |
258 | nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; | ||
259 | 263 | ||
260 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); | 264 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); |
261 | if (ret == 0) { | 265 | if (ret == 0) { |
@@ -396,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
396 | man->io_addr = NULL; | 400 | man->io_addr = NULL; |
397 | man->io_offset = drm_get_resource_start(dev, 1); | 401 | man->io_offset = drm_get_resource_start(dev, 1); |
398 | man->io_size = drm_get_resource_len(dev, 1); | 402 | man->io_size = drm_get_resource_len(dev, 1); |
399 | if (man->io_size > nouveau_mem_fb_amount(dev)) | 403 | if (man->io_size > dev_priv->vram_size) |
400 | man->io_size = nouveau_mem_fb_amount(dev); | 404 | man->io_size = dev_priv->vram_size; |
401 | 405 | ||
402 | man->gpu_offset = dev_priv->vm_vram_base; | 406 | man->gpu_offset = dev_priv->vm_vram_base; |
403 | break; | 407 | break; |
@@ -440,10 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) | |||
440 | 444 | ||
441 | switch (bo->mem.mem_type) { | 445 | switch (bo->mem.mem_type) { |
442 | case TTM_PL_VRAM: | 446 | case TTM_PL_VRAM: |
443 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT); | 447 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT, |
448 | TTM_PL_FLAG_SYSTEM); | ||
444 | break; | 449 | break; |
445 | default: | 450 | default: |
446 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); | 451 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0); |
447 | break; | 452 | break; |
448 | } | 453 | } |
449 | 454 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 6dfb425cbae9..1fc57ef58295 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -142,7 +142,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, | |||
142 | GFP_KERNEL); | 142 | GFP_KERNEL); |
143 | if (!dev_priv->fifos[channel]) | 143 | if (!dev_priv->fifos[channel]) |
144 | return -ENOMEM; | 144 | return -ENOMEM; |
145 | dev_priv->fifo_alloc_count++; | ||
146 | chan = dev_priv->fifos[channel]; | 145 | chan = dev_priv->fifos[channel]; |
147 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); | 146 | INIT_LIST_HEAD(&chan->nvsw.vbl_wait); |
148 | INIT_LIST_HEAD(&chan->fence.pending); | 147 | INIT_LIST_HEAD(&chan->fence.pending); |
@@ -321,7 +320,6 @@ nouveau_channel_free(struct nouveau_channel *chan) | |||
321 | iounmap(chan->user); | 320 | iounmap(chan->user); |
322 | 321 | ||
323 | dev_priv->fifos[chan->id] = NULL; | 322 | dev_priv->fifos[chan->id] = NULL; |
324 | dev_priv->fifo_alloc_count--; | ||
325 | kfree(chan); | 323 | kfree(chan); |
326 | } | 324 | } |
327 | 325 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 8ff9ef5d4b47..a251886a0ce6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c | |||
@@ -137,10 +137,9 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data) | |||
137 | { | 137 | { |
138 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 138 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
139 | struct drm_minor *minor = node->minor; | 139 | struct drm_minor *minor = node->minor; |
140 | struct drm_device *dev = minor->dev; | 140 | struct drm_nouveau_private *dev_priv = minor->dev->dev_private; |
141 | 141 | ||
142 | seq_printf(m, "VRAM total: %dKiB\n", | 142 | seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10)); |
143 | (int)(nouveau_mem_fb_amount(dev) >> 10)); | ||
144 | return 0; | 143 | return 0; |
145 | } | 144 | } |
146 | 145 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index f954ad93e81f..deeb21c6865c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
483 | ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT); | 483 | ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT); |
484 | ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT); | 484 | ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT); |
485 | 485 | ||
486 | for (;;) { | 486 | for (i = 0; i < 16; i++) { |
487 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000); | 487 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000); |
488 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl); | 488 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl); |
489 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000); | 489 | nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000); |
@@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | 504 | ||
505 | if (i == 16) { | ||
506 | NV_ERROR(dev, "auxch DEFER too many times, bailing\n"); | ||
507 | ret = -EREMOTEIO; | ||
508 | goto out; | ||
509 | } | ||
510 | |||
505 | if (cmd & 1) { | 511 | if (cmd & 1) { |
506 | if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) { | 512 | if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) { |
507 | ret = -EREMOTEIO; | 513 | ret = -EREMOTEIO; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d8b559011777..ace630aa89e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -76,6 +76,7 @@ struct nouveau_bo { | |||
76 | struct ttm_buffer_object bo; | 76 | struct ttm_buffer_object bo; |
77 | struct ttm_placement placement; | 77 | struct ttm_placement placement; |
78 | u32 placements[3]; | 78 | u32 placements[3]; |
79 | u32 busy_placements[3]; | ||
79 | struct ttm_bo_kmap_obj kmap; | 80 | struct ttm_bo_kmap_obj kmap; |
80 | struct list_head head; | 81 | struct list_head head; |
81 | 82 | ||
@@ -519,6 +520,7 @@ struct drm_nouveau_private { | |||
519 | 520 | ||
520 | struct workqueue_struct *wq; | 521 | struct workqueue_struct *wq; |
521 | struct work_struct irq_work; | 522 | struct work_struct irq_work; |
523 | struct work_struct hpd_work; | ||
522 | 524 | ||
523 | struct list_head vbl_waiting; | 525 | struct list_head vbl_waiting; |
524 | 526 | ||
@@ -533,7 +535,6 @@ struct drm_nouveau_private { | |||
533 | 535 | ||
534 | struct fb_info *fbdev_info; | 536 | struct fb_info *fbdev_info; |
535 | 537 | ||
536 | int fifo_alloc_count; | ||
537 | struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; | 538 | struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; |
538 | 539 | ||
539 | struct nouveau_engine engine; | 540 | struct nouveau_engine engine; |
@@ -553,12 +554,6 @@ struct drm_nouveau_private { | |||
553 | uint32_t ramro_offset; | 554 | uint32_t ramro_offset; |
554 | uint32_t ramro_size; | 555 | uint32_t ramro_size; |
555 | 556 | ||
556 | /* base physical addresses */ | ||
557 | uint64_t fb_phys; | ||
558 | uint64_t fb_available_size; | ||
559 | uint64_t fb_mappable_pages; | ||
560 | uint64_t fb_aper_free; | ||
561 | |||
562 | struct { | 557 | struct { |
563 | enum { | 558 | enum { |
564 | NOUVEAU_GART_NONE = 0, | 559 | NOUVEAU_GART_NONE = 0, |
@@ -572,10 +567,6 @@ struct drm_nouveau_private { | |||
572 | struct nouveau_gpuobj *sg_ctxdma; | 567 | struct nouveau_gpuobj *sg_ctxdma; |
573 | struct page *sg_dummy_page; | 568 | struct page *sg_dummy_page; |
574 | dma_addr_t sg_dummy_bus; | 569 | dma_addr_t sg_dummy_bus; |
575 | |||
576 | /* nottm hack */ | ||
577 | struct drm_ttm_backend *sg_be; | ||
578 | unsigned long sg_handle; | ||
579 | } gart_info; | 570 | } gart_info; |
580 | 571 | ||
581 | /* nv10-nv40 tiling regions */ | 572 | /* nv10-nv40 tiling regions */ |
@@ -584,6 +575,16 @@ struct drm_nouveau_private { | |||
584 | spinlock_t lock; | 575 | spinlock_t lock; |
585 | } tile; | 576 | } tile; |
586 | 577 | ||
578 | /* VRAM/fb configuration */ | ||
579 | uint64_t vram_size; | ||
580 | uint64_t vram_sys_base; | ||
581 | |||
582 | uint64_t fb_phys; | ||
583 | uint64_t fb_available_size; | ||
584 | uint64_t fb_mappable_pages; | ||
585 | uint64_t fb_aper_free; | ||
586 | int fb_mtrr; | ||
587 | |||
587 | /* G8x/G9x virtual address space */ | 588 | /* G8x/G9x virtual address space */ |
588 | uint64_t vm_gart_base; | 589 | uint64_t vm_gart_base; |
589 | uint64_t vm_gart_size; | 590 | uint64_t vm_gart_size; |
@@ -592,10 +593,6 @@ struct drm_nouveau_private { | |||
592 | uint64_t vm_end; | 593 | uint64_t vm_end; |
593 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; | 594 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; |
594 | int vm_vram_pt_nr; | 595 | int vm_vram_pt_nr; |
595 | uint64_t vram_sys_base; | ||
596 | |||
597 | /* the mtrr covering the FB */ | ||
598 | int fb_mtrr; | ||
599 | 596 | ||
600 | struct mem_block *ramin_heap; | 597 | struct mem_block *ramin_heap; |
601 | 598 | ||
@@ -614,11 +611,7 @@ struct drm_nouveau_private { | |||
614 | uint32_t dac_users[4]; | 611 | uint32_t dac_users[4]; |
615 | 612 | ||
616 | struct nouveau_suspend_resume { | 613 | struct nouveau_suspend_resume { |
617 | uint32_t fifo_mode; | ||
618 | uint32_t graph_ctx_control; | ||
619 | uint32_t graph_state; | ||
620 | uint32_t *ramin_copy; | 614 | uint32_t *ramin_copy; |
621 | uint64_t ramin_size; | ||
622 | } susres; | 615 | } susres; |
623 | 616 | ||
624 | struct backlight_device *backlight; | 617 | struct backlight_device *backlight; |
@@ -717,7 +710,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *, | |||
717 | struct drm_file *, int tail); | 710 | struct drm_file *, int tail); |
718 | extern void nouveau_mem_takedown(struct mem_block **heap); | 711 | extern void nouveau_mem_takedown(struct mem_block **heap); |
719 | extern void nouveau_mem_free_block(struct mem_block *); | 712 | extern void nouveau_mem_free_block(struct mem_block *); |
720 | extern uint64_t nouveau_mem_fb_amount(struct drm_device *); | 713 | extern int nouveau_mem_detect(struct drm_device *dev); |
721 | extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); | 714 | extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap); |
722 | extern int nouveau_mem_init(struct drm_device *); | 715 | extern int nouveau_mem_init(struct drm_device *); |
723 | extern int nouveau_mem_init_agp(struct drm_device *); | 716 | extern int nouveau_mem_init_agp(struct drm_device *); |
@@ -1124,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); | |||
1124 | extern int nouveau_bo_unpin(struct nouveau_bo *); | 1117 | extern int nouveau_bo_unpin(struct nouveau_bo *); |
1125 | extern int nouveau_bo_map(struct nouveau_bo *); | 1118 | extern int nouveau_bo_map(struct nouveau_bo *); |
1126 | extern void nouveau_bo_unmap(struct nouveau_bo *); | 1119 | extern void nouveau_bo_unmap(struct nouveau_bo *); |
1127 | extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype); | 1120 | extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type, |
1121 | uint32_t busy); | ||
1128 | extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | 1122 | extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); |
1129 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1123 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
1130 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1124 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
@@ -1168,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *, | |||
1168 | int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | 1162 | int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); |
1169 | int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); | 1163 | int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); |
1170 | 1164 | ||
1165 | /* nv50_gpio.c */ | ||
1166 | int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | ||
1167 | int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); | ||
1168 | |||
1171 | #ifndef ioread32_native | 1169 | #ifndef ioread32_native |
1172 | #ifdef __BIG_ENDIAN | 1170 | #ifdef __BIG_ENDIAN |
1173 | #define ioread16_native ioread16be | 1171 | #define ioread16_native ioread16be |
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index bc4a24029ed1..9f28b94e479b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -47,6 +47,7 @@ struct nouveau_encoder { | |||
47 | 47 | ||
48 | union { | 48 | union { |
49 | struct { | 49 | struct { |
50 | int mc_unknown; | ||
50 | int dpcd_version; | 51 | int dpcd_version; |
51 | int link_nr; | 52 | int link_nr; |
52 | int link_bw; | 53 | int link_bw; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0d22f66f1c79..1bc0b38a5167 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, | |||
180 | { | 180 | { |
181 | struct nouveau_bo *nvbo = gem->driver_private; | 181 | struct nouveau_bo *nvbo = gem->driver_private; |
182 | struct ttm_buffer_object *bo = &nvbo->bo; | 182 | struct ttm_buffer_object *bo = &nvbo->bo; |
183 | uint64_t flags; | 183 | uint32_t domains = valid_domains & |
184 | (write_domains ? write_domains : read_domains); | ||
185 | uint32_t pref_flags = 0, valid_flags = 0; | ||
184 | 186 | ||
185 | if (!valid_domains || (!read_domains && !write_domains)) | 187 | if (!domains) |
186 | return -EINVAL; | 188 | return -EINVAL; |
187 | 189 | ||
188 | if (write_domains) { | 190 | if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) |
189 | if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && | 191 | valid_flags |= TTM_PL_FLAG_VRAM; |
190 | (write_domains & NOUVEAU_GEM_DOMAIN_VRAM)) | 192 | |
191 | flags = TTM_PL_FLAG_VRAM; | 193 | if (valid_domains & NOUVEAU_GEM_DOMAIN_GART) |
192 | else | 194 | valid_flags |= TTM_PL_FLAG_TT; |
193 | if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && | 195 | |
194 | (write_domains & NOUVEAU_GEM_DOMAIN_GART)) | 196 | if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) && |
195 | flags = TTM_PL_FLAG_TT; | 197 | bo->mem.mem_type == TTM_PL_VRAM) |
196 | else | 198 | pref_flags |= TTM_PL_FLAG_VRAM; |
197 | return -EINVAL; | 199 | |
198 | } else { | 200 | else if ((domains & NOUVEAU_GEM_DOMAIN_GART) && |
199 | if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && | 201 | bo->mem.mem_type == TTM_PL_TT) |
200 | (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) && | 202 | pref_flags |= TTM_PL_FLAG_TT; |
201 | bo->mem.mem_type == TTM_PL_VRAM) | 203 | |
202 | flags = TTM_PL_FLAG_VRAM; | 204 | else if (domains & NOUVEAU_GEM_DOMAIN_VRAM) |
203 | else | 205 | pref_flags |= TTM_PL_FLAG_VRAM; |
204 | if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && | 206 | |
205 | (read_domains & NOUVEAU_GEM_DOMAIN_GART) && | 207 | else |
206 | bo->mem.mem_type == TTM_PL_TT) | 208 | pref_flags |= TTM_PL_FLAG_TT; |
207 | flags = TTM_PL_FLAG_TT; | 209 | |
208 | else | 210 | nouveau_bo_placement_set(nvbo, pref_flags, valid_flags); |
209 | if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && | ||
210 | (read_domains & NOUVEAU_GEM_DOMAIN_VRAM)) | ||
211 | flags = TTM_PL_FLAG_VRAM; | ||
212 | else | ||
213 | flags = TTM_PL_FLAG_TT; | ||
214 | } | ||
215 | 211 | ||
216 | nouveau_bo_placement_set(nvbo, flags); | ||
217 | return 0; | 212 | return 0; |
218 | } | 213 | } |
219 | 214 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 2bd59a92fee5..13e73cee4c44 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev) | |||
51 | 51 | ||
52 | if (dev_priv->card_type == NV_50) { | 52 | if (dev_priv->card_type == NV_50) { |
53 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); | 53 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); |
54 | INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); | ||
54 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); | 55 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); |
55 | } | 56 | } |
56 | } | 57 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 2dc09dbd817d..775a7017af64 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
347 | return -EBUSY; | 347 | return -EBUSY; |
348 | } | 348 | } |
349 | 349 | ||
350 | nv_wr32(dev, 0x100c80, 0x00040001); | ||
351 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
352 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
353 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
354 | return -EBUSY; | ||
355 | } | ||
356 | |||
357 | nv_wr32(dev, 0x100c80, 0x00060001); | ||
358 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
359 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
360 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
361 | return -EBUSY; | ||
362 | } | ||
363 | |||
350 | return 0; | 364 | return 0; |
351 | } | 365 | } |
352 | 366 | ||
@@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | |||
387 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | 401 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { |
388 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | 402 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); |
389 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | 403 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); |
404 | return; | ||
405 | } | ||
406 | |||
407 | nv_wr32(dev, 0x100c80, 0x00040001); | ||
408 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
409 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
410 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | nv_wr32(dev, 0x100c80, 0x00060001); | ||
415 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
416 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
417 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
390 | } | 418 | } |
391 | } | 419 | } |
392 | 420 | ||
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev) | |||
449 | } | 477 | } |
450 | } | 478 | } |
451 | 479 | ||
452 | /*XXX won't work on BSD because of pci_read_config_dword */ | ||
453 | static uint32_t | 480 | static uint32_t |
454 | nouveau_mem_fb_amount_igp(struct drm_device *dev) | 481 | nouveau_mem_detect_nv04(struct drm_device *dev) |
482 | { | ||
483 | uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); | ||
484 | |||
485 | if (boot0 & 0x00000100) | ||
486 | return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; | ||
487 | |||
488 | switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { | ||
489 | case NV04_BOOT_0_RAM_AMOUNT_32MB: | ||
490 | return 32 * 1024 * 1024; | ||
491 | case NV04_BOOT_0_RAM_AMOUNT_16MB: | ||
492 | return 16 * 1024 * 1024; | ||
493 | case NV04_BOOT_0_RAM_AMOUNT_8MB: | ||
494 | return 8 * 1024 * 1024; | ||
495 | case NV04_BOOT_0_RAM_AMOUNT_4MB: | ||
496 | return 4 * 1024 * 1024; | ||
497 | } | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static uint32_t | ||
503 | nouveau_mem_detect_nforce(struct drm_device *dev) | ||
455 | { | 504 | { |
456 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 505 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
457 | struct pci_dev *bridge; | 506 | struct pci_dev *bridge; |
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev) | |||
463 | return 0; | 512 | return 0; |
464 | } | 513 | } |
465 | 514 | ||
466 | if (dev_priv->flags&NV_NFORCE) { | 515 | if (dev_priv->flags & NV_NFORCE) { |
467 | pci_read_config_dword(bridge, 0x7C, &mem); | 516 | pci_read_config_dword(bridge, 0x7C, &mem); |
468 | return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; | 517 | return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024; |
469 | } else | 518 | } else |
470 | if (dev_priv->flags&NV_NFORCE2) { | 519 | if (dev_priv->flags & NV_NFORCE2) { |
471 | pci_read_config_dword(bridge, 0x84, &mem); | 520 | pci_read_config_dword(bridge, 0x84, &mem); |
472 | return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; | 521 | return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024; |
473 | } | 522 | } |
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev) | |||
477 | } | 526 | } |
478 | 527 | ||
479 | /* returns the amount of FB ram in bytes */ | 528 | /* returns the amount of FB ram in bytes */ |
480 | uint64_t nouveau_mem_fb_amount(struct drm_device *dev) | 529 | int |
530 | nouveau_mem_detect(struct drm_device *dev) | ||
481 | { | 531 | { |
482 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 532 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
483 | uint32_t boot0; | 533 | |
484 | 534 | if (dev_priv->card_type == NV_04) { | |
485 | switch (dev_priv->card_type) { | 535 | dev_priv->vram_size = nouveau_mem_detect_nv04(dev); |
486 | case NV_04: | 536 | } else |
487 | boot0 = nv_rd32(dev, NV03_BOOT_0); | 537 | if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { |
488 | if (boot0 & 0x00000100) | 538 | dev_priv->vram_size = nouveau_mem_detect_nforce(dev); |
489 | return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; | 539 | } else { |
490 | 540 | dev_priv->vram_size = nv_rd32(dev, NV04_FIFO_DATA); | |
491 | switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { | 541 | dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; |
492 | case NV04_BOOT_0_RAM_AMOUNT_32MB: | 542 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) |
493 | return 32 * 1024 * 1024; | 543 | dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; |
494 | case NV04_BOOT_0_RAM_AMOUNT_16MB: | ||
495 | return 16 * 1024 * 1024; | ||
496 | case NV04_BOOT_0_RAM_AMOUNT_8MB: | ||
497 | return 8 * 1024 * 1024; | ||
498 | case NV04_BOOT_0_RAM_AMOUNT_4MB: | ||
499 | return 4 * 1024 * 1024; | ||
500 | } | ||
501 | break; | ||
502 | case NV_10: | ||
503 | case NV_20: | ||
504 | case NV_30: | ||
505 | case NV_40: | ||
506 | case NV_50: | ||
507 | default: | ||
508 | if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { | ||
509 | return nouveau_mem_fb_amount_igp(dev); | ||
510 | } else { | ||
511 | uint64_t mem; | ||
512 | mem = (nv_rd32(dev, NV04_FIFO_DATA) & | ||
513 | NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> | ||
514 | NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; | ||
515 | return mem * 1024 * 1024; | ||
516 | } | ||
517 | break; | ||
518 | } | 544 | } |
519 | 545 | ||
520 | NV_ERROR(dev, | 546 | NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); |
521 | "Unable to detect video ram size. Please report your setup to " | 547 | if (dev_priv->vram_sys_base) { |
522 | DRIVER_EMAIL "\n"); | 548 | NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", |
523 | return 0; | 549 | dev_priv->vram_sys_base); |
550 | } | ||
551 | |||
552 | if (dev_priv->vram_size) | ||
553 | return 0; | ||
554 | return -ENOMEM; | ||
524 | } | 555 | } |
525 | 556 | ||
526 | #if __OS_HAS_AGP | 557 | #if __OS_HAS_AGP |
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev) | |||
631 | spin_lock_init(&dev_priv->ttm.bo_list_lock); | 662 | spin_lock_init(&dev_priv->ttm.bo_list_lock); |
632 | spin_lock_init(&dev_priv->tile.lock); | 663 | spin_lock_init(&dev_priv->tile.lock); |
633 | 664 | ||
634 | dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); | 665 | dev_priv->fb_available_size = dev_priv->vram_size; |
635 | |||
636 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; | 666 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; |
637 | if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) | 667 | if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1)) |
638 | dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); | 668 | dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1); |
639 | dev_priv->fb_mappable_pages >>= PAGE_SHIFT; | 669 | dev_priv->fb_mappable_pages >>= PAGE_SHIFT; |
640 | 670 | ||
641 | NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20)); | ||
642 | |||
643 | /* remove reserved space at end of vram from available amount */ | 671 | /* remove reserved space at end of vram from available amount */ |
644 | dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; | 672 | dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; |
645 | dev_priv->fb_aper_free = dev_priv->fb_available_size; | 673 | dev_priv->fb_aper_free = dev_priv->fb_available_size; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 86785b8d42ed..1d6ee8b55154 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -172,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be) | |||
172 | } | 172 | } |
173 | dev_priv->engine.instmem.finish_access(nvbe->dev); | 173 | dev_priv->engine.instmem.finish_access(nvbe->dev); |
174 | 174 | ||
175 | if (dev_priv->card_type == NV_50) { | ||
176 | nv_wr32(dev, 0x100c80, 0x00050001); | ||
177 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
178 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
179 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
180 | nv_rd32(dev, 0x100c80)); | ||
181 | return -EBUSY; | ||
182 | } | ||
183 | |||
184 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
185 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
186 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
187 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", | ||
188 | nv_rd32(dev, 0x100c80)); | ||
189 | return -EBUSY; | ||
190 | } | ||
191 | } | ||
192 | |||
175 | nvbe->bound = false; | 193 | nvbe->bound = false; |
176 | return 0; | 194 | return 0; |
177 | } | 195 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 10656a6be8e6..e1710640a278 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -341,7 +341,7 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
341 | 341 | ||
342 | gpuobj = NULL; | 342 | gpuobj = NULL; |
343 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, | 343 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, |
344 | 0, nouveau_mem_fb_amount(dev), | 344 | 0, dev_priv->vram_size, |
345 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, | 345 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, |
346 | &gpuobj); | 346 | &gpuobj); |
347 | if (ret) | 347 | if (ret) |
@@ -427,6 +427,10 @@ nouveau_card_init(struct drm_device *dev) | |||
427 | goto out; | 427 | goto out; |
428 | } | 428 | } |
429 | 429 | ||
430 | ret = nouveau_mem_detect(dev); | ||
431 | if (ret) | ||
432 | goto out_bios; | ||
433 | |||
430 | ret = nouveau_gpuobj_early_init(dev); | 434 | ret = nouveau_gpuobj_early_init(dev); |
431 | if (ret) | 435 | if (ret) |
432 | goto out_bios; | 436 | goto out_bios; |
@@ -502,7 +506,7 @@ nouveau_card_init(struct drm_device *dev) | |||
502 | else | 506 | else |
503 | ret = nv04_display_create(dev); | 507 | ret = nv04_display_create(dev); |
504 | if (ret) | 508 | if (ret) |
505 | goto out_irq; | 509 | goto out_channel; |
506 | } | 510 | } |
507 | 511 | ||
508 | ret = nouveau_backlight_init(dev); | 512 | ret = nouveau_backlight_init(dev); |
@@ -516,6 +520,11 @@ nouveau_card_init(struct drm_device *dev) | |||
516 | 520 | ||
517 | return 0; | 521 | return 0; |
518 | 522 | ||
523 | out_channel: | ||
524 | if (dev_priv->channel) { | ||
525 | nouveau_channel_free(dev_priv->channel); | ||
526 | dev_priv->channel = NULL; | ||
527 | } | ||
519 | out_irq: | 528 | out_irq: |
520 | drm_irq_uninstall(dev); | 529 | drm_irq_uninstall(dev); |
521 | out_fifo: | 530 | out_fifo: |
@@ -533,6 +542,7 @@ out_mc: | |||
533 | out_gpuobj: | 542 | out_gpuobj: |
534 | nouveau_gpuobj_takedown(dev); | 543 | nouveau_gpuobj_takedown(dev); |
535 | out_mem: | 544 | out_mem: |
545 | nouveau_sgdma_takedown(dev); | ||
536 | nouveau_mem_close(dev); | 546 | nouveau_mem_close(dev); |
537 | out_instmem: | 547 | out_instmem: |
538 | engine->instmem.takedown(dev); | 548 | engine->instmem.takedown(dev); |
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 6b2ef4a9fce1..500ccfd3a0b8 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c | |||
@@ -278,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev) | |||
278 | default: | 278 | default: |
279 | nv_wr32(dev, 0x2230, 0); | 279 | nv_wr32(dev, 0x2230, 0); |
280 | nv_wr32(dev, NV40_PFIFO_RAMFC, | 280 | nv_wr32(dev, NV40_PFIFO_RAMFC, |
281 | ((nouveau_mem_fb_amount(dev) - 512 * 1024 + | 281 | ((dev_priv->vram_size - 512 * 1024 + |
282 | dev_priv->ramfc_offset) >> 16) | (3 << 16)); | 282 | dev_priv->ramfc_offset) >> 16) | (3 << 16)); |
283 | break; | 283 | break; |
284 | } | 284 | } |
diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 53e8afe1dcd1..0616c96e4b67 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c | |||
@@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev) | |||
335 | nv_wr32(dev, 0x400b38, 0x2ffff800); | 335 | nv_wr32(dev, 0x400b38, 0x2ffff800); |
336 | nv_wr32(dev, 0x400b3c, 0x00006000); | 336 | nv_wr32(dev, 0x400b3c, 0x00006000); |
337 | 337 | ||
338 | /* Tiling related stuff. */ | ||
339 | switch (dev_priv->chipset) { | ||
340 | case 0x44: | ||
341 | case 0x4a: | ||
342 | nv_wr32(dev, 0x400bc4, 0x1003d888); | ||
343 | nv_wr32(dev, 0x400bbc, 0xb7a7b500); | ||
344 | break; | ||
345 | case 0x46: | ||
346 | nv_wr32(dev, 0x400bc4, 0x0000e024); | ||
347 | nv_wr32(dev, 0x400bbc, 0xb7a7b520); | ||
348 | break; | ||
349 | case 0x4c: | ||
350 | case 0x4e: | ||
351 | case 0x67: | ||
352 | nv_wr32(dev, 0x400bc4, 0x1003d888); | ||
353 | nv_wr32(dev, 0x400bbc, 0xb7a7b540); | ||
354 | break; | ||
355 | default: | ||
356 | break; | ||
357 | } | ||
358 | |||
338 | /* Turn all the tiling regions off. */ | 359 | /* Turn all the tiling regions off. */ |
339 | for (i = 0; i < pfb->num_tiles; i++) | 360 | for (i = 0; i < pfb->num_tiles; i++) |
340 | nv40_graph_set_region_tiling(dev, i, 0, 0, 0); | 361 | nv40_graph_set_region_tiling(dev, i, 0, 0, 0); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index fac6c88a2b1f..649db4c1b690 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) | |||
143 | } | 143 | } |
144 | 144 | ||
145 | ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, | 145 | ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, |
146 | 0, nouveau_mem_fb_amount(dev)); | 146 | 0, dev_priv->vram_size); |
147 | if (ret) { | 147 | if (ret) { |
148 | nv50_evo_channel_del(pchan); | 148 | nv50_evo_channel_del(pchan); |
149 | return ret; | 149 | return ret; |
@@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev) | |||
231 | /* This used to be in crtc unblank, but seems out of place there. */ | 231 | /* This used to be in crtc unblank, but seems out of place there. */ |
232 | nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); | 232 | nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); |
233 | /* RAM is clamped to 256 MiB. */ | 233 | /* RAM is clamped to 256 MiB. */ |
234 | ram_amount = nouveau_mem_fb_amount(dev); | 234 | ram_amount = dev_priv->vram_size; |
235 | NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount); | 235 | NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount); |
236 | if (ram_amount > 256*1024*1024) | 236 | if (ram_amount > 256*1024*1024) |
237 | ram_amount = 256*1024*1024; | 237 | ram_amount = 256*1024*1024; |
@@ -529,8 +529,10 @@ int nv50_display_create(struct drm_device *dev) | |||
529 | } | 529 | } |
530 | 530 | ||
531 | ret = nv50_display_init(dev); | 531 | ret = nv50_display_init(dev); |
532 | if (ret) | 532 | if (ret) { |
533 | nv50_display_destroy(dev); | ||
533 | return ret; | 534 | return ret; |
535 | } | ||
534 | 536 | ||
535 | return 0; | 537 | return 0; |
536 | } | 538 | } |
@@ -885,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev) | |||
885 | nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); | 887 | nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); |
886 | } | 888 | } |
887 | 889 | ||
888 | static void | 890 | void |
889 | nv50_display_irq_hotplug(struct drm_device *dev) | 891 | nv50_display_irq_hotplug_bh(struct work_struct *work) |
890 | { | 892 | { |
891 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 893 | struct drm_nouveau_private *dev_priv = |
894 | container_of(work, struct drm_nouveau_private, hpd_work); | ||
895 | struct drm_device *dev = dev_priv->dev; | ||
892 | struct drm_connector *connector; | 896 | struct drm_connector *connector; |
893 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | 897 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; |
894 | uint32_t unplug_mask, plug_mask, change_mask; | 898 | uint32_t unplug_mask, plug_mask, change_mask; |
@@ -949,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev) | |||
949 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 953 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
950 | uint32_t delayed = 0; | 954 | uint32_t delayed = 0; |
951 | 955 | ||
952 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) | 956 | if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { |
953 | nv50_display_irq_hotplug(dev); | 957 | if (!work_pending(&dev_priv->hpd_work)) |
958 | queue_work(dev_priv->wq, &dev_priv->hpd_work); | ||
959 | } | ||
954 | 960 | ||
955 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { | 961 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { |
956 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); | 962 | uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 3ae8d0725f63..581d405ac014 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | void nv50_display_irq_handler(struct drm_device *dev); | 38 | void nv50_display_irq_handler(struct drm_device *dev); |
39 | void nv50_display_irq_handler_bh(struct work_struct *work); | 39 | void nv50_display_irq_handler_bh(struct work_struct *work); |
40 | void nv50_display_irq_hotplug_bh(struct work_struct *work); | ||
40 | int nv50_display_init(struct drm_device *dev); | 41 | int nv50_display_init(struct drm_device *dev); |
41 | int nv50_display_create(struct drm_device *dev); | 42 | int nv50_display_create(struct drm_device *dev); |
42 | int nv50_display_destroy(struct drm_device *dev); | 43 | int nv50_display_destroy(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 25a3cd8794f9..a8c70e7e9184 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
@@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
157 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 157 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
158 | struct nouveau_channel *chan = dev_priv->channel; | 158 | struct nouveau_channel *chan = dev_priv->channel; |
159 | struct nouveau_gpuobj *eng2d = NULL; | 159 | struct nouveau_gpuobj *eng2d = NULL; |
160 | uint64_t fb; | ||
160 | int ret, format; | 161 | int ret, format; |
161 | 162 | ||
163 | fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base; | ||
164 | |||
162 | switch (info->var.bits_per_pixel) { | 165 | switch (info->var.bits_per_pixel) { |
163 | case 8: | 166 | case 8: |
164 | format = 0xf3; | 167 | format = 0xf3; |
@@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
248 | OUT_RING(chan, info->fix.line_length); | 251 | OUT_RING(chan, info->fix.line_length); |
249 | OUT_RING(chan, info->var.xres_virtual); | 252 | OUT_RING(chan, info->var.xres_virtual); |
250 | OUT_RING(chan, info->var.yres_virtual); | 253 | OUT_RING(chan, info->var.yres_virtual); |
251 | OUT_RING(chan, 0); | 254 | OUT_RING(chan, upper_32_bits(fb)); |
252 | OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + | 255 | OUT_RING(chan, lower_32_bits(fb)); |
253 | dev_priv->vm_vram_base); | ||
254 | BEGIN_RING(chan, NvSub2D, 0x0230, 2); | 256 | BEGIN_RING(chan, NvSub2D, 0x0230, 2); |
255 | OUT_RING(chan, format); | 257 | OUT_RING(chan, format); |
256 | OUT_RING(chan, 1); | 258 | OUT_RING(chan, 1); |
@@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
258 | OUT_RING(chan, info->fix.line_length); | 260 | OUT_RING(chan, info->fix.line_length); |
259 | OUT_RING(chan, info->var.xres_virtual); | 261 | OUT_RING(chan, info->var.xres_virtual); |
260 | OUT_RING(chan, info->var.yres_virtual); | 262 | OUT_RING(chan, info->var.yres_virtual); |
261 | OUT_RING(chan, 0); | 263 | OUT_RING(chan, upper_32_bits(fb)); |
262 | OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + | 264 | OUT_RING(chan, lower_32_bits(fb)); |
263 | dev_priv->vm_vram_base); | ||
264 | 265 | ||
265 | return 0; | 266 | return 0; |
266 | } | 267 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c new file mode 100644 index 000000000000..c61782b314e7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "drmP.h" | ||
26 | #include "nouveau_drv.h" | ||
27 | #include "nouveau_hw.h" | ||
28 | |||
29 | static int | ||
30 | nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) | ||
31 | { | ||
32 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | ||
33 | |||
34 | if (gpio->line > 32) | ||
35 | return -EINVAL; | ||
36 | |||
37 | *reg = nv50_gpio_reg[gpio->line >> 3]; | ||
38 | *shift = (gpio->line & 7) << 2; | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | int | ||
43 | nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) | ||
44 | { | ||
45 | struct dcb_gpio_entry *gpio; | ||
46 | uint32_t r, s, v; | ||
47 | |||
48 | gpio = nouveau_bios_gpio_entry(dev, tag); | ||
49 | if (!gpio) | ||
50 | return -ENOENT; | ||
51 | |||
52 | if (nv50_gpio_location(gpio, &r, &s)) | ||
53 | return -EINVAL; | ||
54 | |||
55 | v = nv_rd32(dev, r) >> (s + 2); | ||
56 | return ((v & 1) == (gpio->state[1] & 1)); | ||
57 | } | ||
58 | |||
59 | int | ||
60 | nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) | ||
61 | { | ||
62 | struct dcb_gpio_entry *gpio; | ||
63 | uint32_t r, s, v; | ||
64 | |||
65 | gpio = nouveau_bios_gpio_entry(dev, tag); | ||
66 | if (!gpio) | ||
67 | return -ENOENT; | ||
68 | |||
69 | if (nv50_gpio_location(gpio, &r, &s)) | ||
70 | return -EINVAL; | ||
71 | |||
72 | v = nv_rd32(dev, r) & ~(0x3 << s); | ||
73 | v |= (gpio->state[state] ^ 2) << s; | ||
74 | nv_wr32(dev, r, v); | ||
75 | return 0; | ||
76 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index c62b33a02f88..b203d06f601f 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -410,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = { | |||
410 | { 0x5039, false, NULL }, /* m2mf */ | 410 | { 0x5039, false, NULL }, /* m2mf */ |
411 | { 0x502d, false, NULL }, /* 2d */ | 411 | { 0x502d, false, NULL }, /* 2d */ |
412 | { 0x50c0, false, NULL }, /* compute */ | 412 | { 0x50c0, false, NULL }, /* compute */ |
413 | { 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */ | ||
413 | { 0x5097, false, NULL }, /* tesla (nv50) */ | 414 | { 0x5097, false, NULL }, /* tesla (nv50) */ |
414 | { 0x8297, false, NULL }, /* tesla (nv80/nv90) */ | 415 | { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */ |
415 | { 0x8397, false, NULL }, /* tesla (nva0) */ | 416 | { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */ |
416 | { 0x8597, false, NULL }, /* tesla (nva8) */ | 417 | { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ |
417 | {} | 418 | {} |
418 | }; | 419 | }; |
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index 546b31949a30..42a8fb20c1e6 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c | |||
@@ -55,12 +55,12 @@ | |||
55 | #define CP_FLAG_AUTO_LOAD ((2 * 32) + 5) | 55 | #define CP_FLAG_AUTO_LOAD ((2 * 32) + 5) |
56 | #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 | 56 | #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 |
57 | #define CP_FLAG_AUTO_LOAD_PENDING 1 | 57 | #define CP_FLAG_AUTO_LOAD_PENDING 1 |
58 | #define CP_FLAG_NEWCTX ((2 * 32) + 10) | ||
59 | #define CP_FLAG_NEWCTX_BUSY 0 | ||
60 | #define CP_FLAG_NEWCTX_DONE 1 | ||
58 | #define CP_FLAG_XFER ((2 * 32) + 11) | 61 | #define CP_FLAG_XFER ((2 * 32) + 11) |
59 | #define CP_FLAG_XFER_IDLE 0 | 62 | #define CP_FLAG_XFER_IDLE 0 |
60 | #define CP_FLAG_XFER_BUSY 1 | 63 | #define CP_FLAG_XFER_BUSY 1 |
61 | #define CP_FLAG_NEWCTX ((2 * 32) + 12) | ||
62 | #define CP_FLAG_NEWCTX_BUSY 0 | ||
63 | #define CP_FLAG_NEWCTX_DONE 1 | ||
64 | #define CP_FLAG_ALWAYS ((2 * 32) + 13) | 64 | #define CP_FLAG_ALWAYS ((2 * 32) + 13) |
65 | #define CP_FLAG_ALWAYS_FALSE 0 | 65 | #define CP_FLAG_ALWAYS_FALSE 0 |
66 | #define CP_FLAG_ALWAYS_TRUE 1 | 66 | #define CP_FLAG_ALWAYS_TRUE 1 |
@@ -177,6 +177,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx) | |||
177 | case 0x96: | 177 | case 0x96: |
178 | case 0x98: | 178 | case 0x98: |
179 | case 0xa0: | 179 | case 0xa0: |
180 | case 0xa3: | ||
180 | case 0xa5: | 181 | case 0xa5: |
181 | case 0xa8: | 182 | case 0xa8: |
182 | case 0xaa: | 183 | case 0xaa: |
@@ -364,6 +365,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
364 | case 0xac: | 365 | case 0xac: |
365 | gr_def(ctx, 0x401c00, 0x042500df); | 366 | gr_def(ctx, 0x401c00, 0x042500df); |
366 | break; | 367 | break; |
368 | case 0xa3: | ||
367 | case 0xa5: | 369 | case 0xa5: |
368 | case 0xa8: | 370 | case 0xa8: |
369 | gr_def(ctx, 0x401c00, 0x142500df); | 371 | gr_def(ctx, 0x401c00, 0x142500df); |
@@ -418,6 +420,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
418 | break; | 420 | break; |
419 | case 0x84: | 421 | case 0x84: |
420 | case 0xa0: | 422 | case 0xa0: |
423 | case 0xa3: | ||
421 | case 0xa5: | 424 | case 0xa5: |
422 | case 0xa8: | 425 | case 0xa8: |
423 | case 0xaa: | 426 | case 0xaa: |
@@ -792,6 +795,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
792 | case 0xa5: | 795 | case 0xa5: |
793 | gr_def(ctx, offset + 0x1c, 0x310c0000); | 796 | gr_def(ctx, offset + 0x1c, 0x310c0000); |
794 | break; | 797 | break; |
798 | case 0xa3: | ||
795 | case 0xa8: | 799 | case 0xa8: |
796 | case 0xaa: | 800 | case 0xaa: |
797 | case 0xac: | 801 | case 0xac: |
@@ -859,6 +863,8 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | |||
859 | else | 863 | else |
860 | gr_def(ctx, offset + 0x8, 0x05010202); | 864 | gr_def(ctx, offset + 0x8, 0x05010202); |
861 | gr_def(ctx, offset + 0xc, 0x00030201); | 865 | gr_def(ctx, offset + 0xc, 0x00030201); |
866 | if (dev_priv->chipset == 0xa3) | ||
867 | cp_ctx(ctx, base + 0x36c, 1); | ||
862 | 868 | ||
863 | cp_ctx(ctx, base + 0x400, 2); | 869 | cp_ctx(ctx, base + 0x400, 2); |
864 | gr_def(ctx, base + 0x404, 0x00000040); | 870 | gr_def(ctx, base + 0x404, 0x00000040); |
@@ -1159,7 +1165,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) | |||
1159 | nv50_graph_construct_gene_unk8(ctx); | 1165 | nv50_graph_construct_gene_unk8(ctx); |
1160 | if (dev_priv->chipset == 0xa0) | 1166 | if (dev_priv->chipset == 0xa0) |
1161 | xf_emit(ctx, 0x189, 0); | 1167 | xf_emit(ctx, 0x189, 0); |
1162 | else if (dev_priv->chipset < 0xa8) | 1168 | else if (dev_priv->chipset == 0xa3) |
1169 | xf_emit(ctx, 0xd5, 0); | ||
1170 | else if (dev_priv->chipset == 0xa5) | ||
1163 | xf_emit(ctx, 0x99, 0); | 1171 | xf_emit(ctx, 0x99, 0); |
1164 | else if (dev_priv->chipset == 0xaa) | 1172 | else if (dev_priv->chipset == 0xaa) |
1165 | xf_emit(ctx, 0x65, 0); | 1173 | xf_emit(ctx, 0x65, 0); |
@@ -1197,6 +1205,8 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) | |||
1197 | ctx->ctxvals_pos = offset + 4; | 1205 | ctx->ctxvals_pos = offset + 4; |
1198 | if (dev_priv->chipset == 0xa0) | 1206 | if (dev_priv->chipset == 0xa0) |
1199 | xf_emit(ctx, 0xa80, 0); | 1207 | xf_emit(ctx, 0xa80, 0); |
1208 | else if (dev_priv->chipset == 0xa3) | ||
1209 | xf_emit(ctx, 0xa7c, 0); | ||
1200 | else | 1210 | else |
1201 | xf_emit(ctx, 0xa7a, 0); | 1211 | xf_emit(ctx, 0xa7a, 0); |
1202 | xf_emit(ctx, 1, 0x3fffff); | 1212 | xf_emit(ctx, 1, 0x3fffff); |
@@ -1341,6 +1351,7 @@ nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx) | |||
1341 | xf_emit(ctx, 0x942, 0); | 1351 | xf_emit(ctx, 0x942, 0); |
1342 | break; | 1352 | break; |
1343 | case 0xa0: | 1353 | case 0xa0: |
1354 | case 0xa3: | ||
1344 | xf_emit(ctx, 0x2042, 0); | 1355 | xf_emit(ctx, 0x2042, 0); |
1345 | break; | 1356 | break; |
1346 | case 0xa5: | 1357 | case 0xa5: |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index de1f5b0062c5..5f21df31f3aa 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev) | |||
63 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 63 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
64 | struct nouveau_channel *chan; | 64 | struct nouveau_channel *chan; |
65 | uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; | 65 | uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; |
66 | uint32_t save_nv001700; | ||
67 | uint64_t v; | ||
66 | struct nv50_instmem_priv *priv; | 68 | struct nv50_instmem_priv *priv; |
67 | int ret, i; | 69 | int ret, i; |
68 | uint32_t v, save_nv001700; | ||
69 | 70 | ||
70 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 71 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
71 | if (!priv) | 72 | if (!priv) |
@@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev) | |||
76 | for (i = 0x1700; i <= 0x1710; i += 4) | 77 | for (i = 0x1700; i <= 0x1710; i += 4) |
77 | priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); | 78 | priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); |
78 | 79 | ||
79 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) | ||
80 | dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; | ||
81 | else | ||
82 | dev_priv->vram_sys_base = 0; | ||
83 | |||
84 | /* Reserve the last MiB of VRAM, we should probably try to avoid | 80 | /* Reserve the last MiB of VRAM, we should probably try to avoid |
85 | * setting up the below tables over the top of the VBIOS image at | 81 | * setting up the below tables over the top of the VBIOS image at |
86 | * some point. | 82 | * some point. |
87 | */ | 83 | */ |
88 | dev_priv->ramin_rsvd_vram = 1 << 20; | 84 | dev_priv->ramin_rsvd_vram = 1 << 20; |
89 | c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram; | 85 | c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; |
90 | c_size = 128 << 10; | 86 | c_size = 128 << 10; |
91 | c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; | 87 | c_vmpd = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200; |
92 | c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; | 88 | c_ramfc = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; |
@@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
106 | dev_priv->vm_gart_size = NV50_VM_BLOCK; | 102 | dev_priv->vm_gart_size = NV50_VM_BLOCK; |
107 | 103 | ||
108 | dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; | 104 | dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; |
109 | dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev); | 105 | dev_priv->vm_vram_size = dev_priv->vram_size; |
110 | if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) | 106 | if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) |
111 | dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; | 107 | dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; |
112 | dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); | 108 | dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); |
@@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev) | |||
189 | 185 | ||
190 | i = 0; | 186 | i = 0; |
191 | while (v < dev_priv->vram_sys_base + c_offset + c_size) { | 187 | while (v < dev_priv->vram_sys_base + c_offset + c_size) { |
192 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v); | 188 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v)); |
193 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); | 189 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v)); |
194 | v += 0x1000; | 190 | v += 0x1000; |
195 | i += 8; | 191 | i += 8; |
196 | } | 192 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index c2fff543b06f..0c68698f23df 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
211 | mode_ctl = 0x0200; | 211 | mode_ctl = 0x0200; |
212 | break; | 212 | break; |
213 | case OUTPUT_DP: | 213 | case OUTPUT_DP: |
214 | mode_ctl |= 0x00050000; | 214 | mode_ctl |= (nv_encoder->dp.mc_unknown << 16); |
215 | if (nv_encoder->dcb->sorconf.link & 1) | 215 | if (nv_encoder->dcb->sorconf.link & 1) |
216 | mode_ctl |= 0x00000800; | 216 | mode_ctl |= 0x00000800; |
217 | else | 217 | else |
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { | |||
274 | int | 274 | int |
275 | nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | 275 | nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) |
276 | { | 276 | { |
277 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
277 | struct nouveau_encoder *nv_encoder = NULL; | 278 | struct nouveau_encoder *nv_encoder = NULL; |
278 | struct drm_encoder *encoder; | 279 | struct drm_encoder *encoder; |
279 | bool dum; | 280 | bool dum; |
@@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) | |||
319 | encoder->possible_crtcs = entry->heads; | 320 | encoder->possible_crtcs = entry->heads; |
320 | encoder->possible_clones = 0; | 321 | encoder->possible_clones = 0; |
321 | 322 | ||
323 | if (nv_encoder->dcb->type == OUTPUT_DP) { | ||
324 | uint32_t mc, or = nv_encoder->or; | ||
325 | |||
326 | if (dev_priv->chipset < 0x90 || | ||
327 | dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) | ||
328 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or)); | ||
329 | else | ||
330 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or)); | ||
331 | |||
332 | switch ((mc & 0x00000f00) >> 8) { | ||
333 | case 8: | ||
334 | case 9: | ||
335 | nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16; | ||
336 | break; | ||
337 | default: | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | if (!nv_encoder->dp.mc_unknown) | ||
342 | nv_encoder->dp.mc_unknown = 5; | ||
343 | } | ||
344 | |||
322 | return 0; | 345 | return 0; |
323 | } | 346 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 07b7ebf1f466..1d569830ed99 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -908,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg) | |||
908 | uint8_t attr = U8((*ptr)++), shift; | 908 | uint8_t attr = U8((*ptr)++), shift; |
909 | uint32_t saved, dst; | 909 | uint32_t saved, dst; |
910 | int dptr = *ptr; | 910 | int dptr = *ptr; |
911 | uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; | ||
911 | SDEBUG(" dst: "); | 912 | SDEBUG(" dst: "); |
912 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 913 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
914 | /* op needs to full dst value */ | ||
915 | dst = saved; | ||
913 | shift = atom_get_src(ctx, attr, ptr); | 916 | shift = atom_get_src(ctx, attr, ptr); |
914 | SDEBUG(" shift: %d\n", shift); | 917 | SDEBUG(" shift: %d\n", shift); |
915 | dst <<= shift; | 918 | dst <<= shift; |
919 | dst &= atom_arg_mask[dst_align]; | ||
920 | dst >>= atom_arg_shift[dst_align]; | ||
916 | SDEBUG(" dst: "); | 921 | SDEBUG(" dst: "); |
917 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | 922 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); |
918 | } | 923 | } |
@@ -922,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg) | |||
922 | uint8_t attr = U8((*ptr)++), shift; | 927 | uint8_t attr = U8((*ptr)++), shift; |
923 | uint32_t saved, dst; | 928 | uint32_t saved, dst; |
924 | int dptr = *ptr; | 929 | int dptr = *ptr; |
930 | uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3]; | ||
925 | SDEBUG(" dst: "); | 931 | SDEBUG(" dst: "); |
926 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); | 932 | dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); |
933 | /* op needs to full dst value */ | ||
934 | dst = saved; | ||
927 | shift = atom_get_src(ctx, attr, ptr); | 935 | shift = atom_get_src(ctx, attr, ptr); |
928 | SDEBUG(" shift: %d\n", shift); | 936 | SDEBUG(" shift: %d\n", shift); |
929 | dst >>= shift; | 937 | dst >>= shift; |
938 | dst &= atom_arg_mask[dst_align]; | ||
939 | dst >>= atom_arg_shift[dst_align]; | ||
930 | SDEBUG(" dst: "); | 940 | SDEBUG(" dst: "); |
931 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); | 941 | atom_put_dst(ctx, arg, attr, &dptr, dst, saved); |
932 | } | 942 | } |
@@ -1137,6 +1147,7 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32 | |||
1137 | int len, ws, ps, ptr; | 1147 | int len, ws, ps, ptr; |
1138 | unsigned char op; | 1148 | unsigned char op; |
1139 | atom_exec_context ectx; | 1149 | atom_exec_context ectx; |
1150 | int ret = 0; | ||
1140 | 1151 | ||
1141 | if (!base) | 1152 | if (!base) |
1142 | return -EINVAL; | 1153 | return -EINVAL; |
@@ -1169,7 +1180,8 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32 | |||
1169 | if (ectx.abort) { | 1180 | if (ectx.abort) { |
1170 | DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n", | 1181 | DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n", |
1171 | base, len, ws, ps, ptr - 1); | 1182 | base, len, ws, ps, ptr - 1); |
1172 | return -EINVAL; | 1183 | ret = -EINVAL; |
1184 | goto free; | ||
1173 | } | 1185 | } |
1174 | 1186 | ||
1175 | if (op < ATOM_OP_CNT && op > 0) | 1187 | if (op < ATOM_OP_CNT && op > 0) |
@@ -1184,9 +1196,10 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32 | |||
1184 | debug_depth--; | 1196 | debug_depth--; |
1185 | SDEBUG("<<\n"); | 1197 | SDEBUG("<<\n"); |
1186 | 1198 | ||
1199 | free: | ||
1187 | if (ws) | 1200 | if (ws) |
1188 | kfree(ectx.ws); | 1201 | kfree(ectx.ws); |
1189 | return 0; | 1202 | return ret; |
1190 | } | 1203 | } |
1191 | 1204 | ||
1192 | int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1205 | int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index fd4ef6d18849..a87990b3ae84 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -521,6 +521,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
521 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 521 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
522 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 522 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
523 | adjusted_clock = mode->clock * 2; | 523 | adjusted_clock = mode->clock * 2; |
524 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { | ||
525 | pll->algo = PLL_ALGO_LEGACY; | ||
526 | pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; | ||
527 | } | ||
524 | } else { | 528 | } else { |
525 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) | 529 | if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) |
526 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; | 530 | pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index c9580497ede4..d7388fdb6d0b 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2891,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, | |||
2891 | { | 2891 | { |
2892 | struct radeon_bo *robj; | 2892 | struct radeon_bo *robj; |
2893 | unsigned long size; | 2893 | unsigned long size; |
2894 | unsigned u, i, w, h; | 2894 | unsigned u, i, w, h, d; |
2895 | int ret; | 2895 | int ret; |
2896 | 2896 | ||
2897 | for (u = 0; u < track->num_texture; u++) { | 2897 | for (u = 0; u < track->num_texture; u++) { |
@@ -2923,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, | |||
2923 | h = h / (1 << i); | 2923 | h = h / (1 << i); |
2924 | if (track->textures[u].roundup_h) | 2924 | if (track->textures[u].roundup_h) |
2925 | h = roundup_pow_of_two(h); | 2925 | h = roundup_pow_of_two(h); |
2926 | if (track->textures[u].tex_coord_type == 1) { | ||
2927 | d = (1 << track->textures[u].txdepth) / (1 << i); | ||
2928 | if (!d) | ||
2929 | d = 1; | ||
2930 | } else { | ||
2931 | d = 1; | ||
2932 | } | ||
2926 | if (track->textures[u].compress_format) { | 2933 | if (track->textures[u].compress_format) { |
2927 | 2934 | ||
2928 | size += r100_track_compress_size(track->textures[u].compress_format, w, h); | 2935 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; |
2929 | /* compressed textures are block based */ | 2936 | /* compressed textures are block based */ |
2930 | } else | 2937 | } else |
2931 | size += w * h; | 2938 | size += w * h * d; |
2932 | } | 2939 | } |
2933 | size *= track->textures[u].cpp; | 2940 | size *= track->textures[u].cpp; |
2934 | 2941 | ||
2935 | switch (track->textures[u].tex_coord_type) { | 2942 | switch (track->textures[u].tex_coord_type) { |
2936 | case 0: | 2943 | case 0: |
2937 | break; | ||
2938 | case 1: | 2944 | case 1: |
2939 | size *= (1 << track->textures[u].txdepth); | ||
2940 | break; | 2945 | break; |
2941 | case 2: | 2946 | case 2: |
2942 | if (track->separate_cube) { | 2947 | if (track->separate_cube) { |
@@ -3007,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3007 | } | 3012 | } |
3008 | } | 3013 | } |
3009 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | 3014 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
3010 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; | 3015 | if (track->vap_vf_cntl & (1 << 14)) { |
3016 | nverts = track->vap_alt_nverts; | ||
3017 | } else { | ||
3018 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; | ||
3019 | } | ||
3011 | switch (prim_walk) { | 3020 | switch (prim_walk) { |
3012 | case 1: | 3021 | case 1: |
3013 | for (i = 0; i < track->num_arrays; i++) { | 3022 | for (i = 0; i < track->num_arrays; i++) { |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index b27a6999d219..fadfe68de9cc 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h | |||
@@ -64,6 +64,7 @@ struct r100_cs_track { | |||
64 | unsigned maxy; | 64 | unsigned maxy; |
65 | unsigned vtx_size; | 65 | unsigned vtx_size; |
66 | unsigned vap_vf_cntl; | 66 | unsigned vap_vf_cntl; |
67 | unsigned vap_alt_nverts; | ||
67 | unsigned immd_dwords; | 68 | unsigned immd_dwords; |
68 | unsigned num_arrays; | 69 | unsigned num_arrays; |
69 | unsigned max_indx; | 70 | unsigned max_indx; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 561048a7c0a4..bd75f99bd65e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -325,11 +325,12 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
325 | 325 | ||
326 | r100_hdp_reset(rdev); | 326 | r100_hdp_reset(rdev); |
327 | /* FIXME: rv380 one pipes ? */ | 327 | /* FIXME: rv380 one pipes ? */ |
328 | if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) { | 328 | if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || |
329 | (rdev->family == CHIP_R350)) { | ||
329 | /* r300,r350 */ | 330 | /* r300,r350 */ |
330 | rdev->num_gb_pipes = 2; | 331 | rdev->num_gb_pipes = 2; |
331 | } else { | 332 | } else { |
332 | /* rv350,rv370,rv380 */ | 333 | /* rv350,rv370,rv380,r300 AD */ |
333 | rdev->num_gb_pipes = 1; | 334 | rdev->num_gb_pipes = 1; |
334 | } | 335 | } |
335 | rdev->num_z_pipes = 1; | 336 | rdev->num_z_pipes = 1; |
@@ -729,6 +730,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
729 | /* VAP_VF_MAX_VTX_INDX */ | 730 | /* VAP_VF_MAX_VTX_INDX */ |
730 | track->max_indx = idx_value & 0x00FFFFFFUL; | 731 | track->max_indx = idx_value & 0x00FFFFFFUL; |
731 | break; | 732 | break; |
733 | case 0x2088: | ||
734 | /* VAP_ALT_NUM_VERTICES - only valid on r500 */ | ||
735 | if (p->rdev->family < CHIP_RV515) | ||
736 | goto fail; | ||
737 | track->vap_alt_nverts = idx_value & 0xFFFFFF; | ||
738 | break; | ||
732 | case 0x43E4: | 739 | case 0x43E4: |
733 | /* SC_SCISSOR1 */ | 740 | /* SC_SCISSOR1 */ |
734 | track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; | 741 | track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; |
@@ -766,7 +773,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
766 | tmp = idx_value & ~(0x7 << 16); | 773 | tmp = idx_value & ~(0x7 << 16); |
767 | tmp |= tile_flags; | 774 | tmp |= tile_flags; |
768 | ib[idx] = tmp; | 775 | ib[idx] = tmp; |
769 | |||
770 | i = (reg - 0x4E38) >> 2; | 776 | i = (reg - 0x4E38) >> 2; |
771 | track->cb[i].pitch = idx_value & 0x3FFE; | 777 | track->cb[i].pitch = idx_value & 0x3FFE; |
772 | switch (((idx_value >> 21) & 0xF)) { | 778 | switch (((idx_value >> 21) & 0xF)) { |
@@ -1051,11 +1057,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
1051 | break; | 1057 | break; |
1052 | /* fallthrough do not move */ | 1058 | /* fallthrough do not move */ |
1053 | default: | 1059 | default: |
1054 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 1060 | goto fail; |
1055 | reg, idx); | ||
1056 | return -EINVAL; | ||
1057 | } | 1061 | } |
1058 | return 0; | 1062 | return 0; |
1063 | fail: | ||
1064 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | ||
1065 | reg, idx); | ||
1066 | return -EINVAL; | ||
1059 | } | 1067 | } |
1060 | 1068 | ||
1061 | static int r300_packet3_check(struct radeon_cs_parser *p, | 1069 | static int r300_packet3_check(struct radeon_cs_parser *p, |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index dac7042b797e..1d898051c631 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
37 | { | 37 | { |
38 | return rdev->family >= CHIP_R600 | 38 | return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR) |
39 | || rdev->family == CHIP_RS600 | 39 | || rdev->family == CHIP_RS600 |
40 | || rdev->family == CHIP_RS690 | 40 | || rdev->family == CHIP_RS690 |
41 | || rdev->family == CHIP_RS740; | 41 | || rdev->family == CHIP_RS740; |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 029fa1406d1d..2616b822ba68 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
314 | struct radeon_device *rdev = dev->dev_private; | 314 | struct radeon_device *rdev = dev->dev_private; |
315 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 315 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; |
316 | 316 | ||
317 | if (ASIC_IS_DCE4(rdev)) | ||
318 | return; | ||
319 | |||
317 | if (!offset) | 320 | if (!offset) |
318 | return; | 321 | return; |
319 | 322 | ||
@@ -484,6 +487,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
484 | struct radeon_device *rdev = dev->dev_private; | 487 | struct radeon_device *rdev = dev->dev_private; |
485 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 488 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
486 | 489 | ||
490 | if (ASIC_IS_DCE4(rdev)) | ||
491 | return; | ||
492 | |||
487 | if (!radeon_encoder->hdmi_offset) { | 493 | if (!radeon_encoder->hdmi_offset) { |
488 | r600_hdmi_assign_block(encoder); | 494 | r600_hdmi_assign_block(encoder); |
489 | if (!radeon_encoder->hdmi_offset) { | 495 | if (!radeon_encoder->hdmi_offset) { |
@@ -525,6 +531,9 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
525 | struct radeon_device *rdev = dev->dev_private; | 531 | struct radeon_device *rdev = dev->dev_private; |
526 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 532 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
527 | 533 | ||
534 | if (ASIC_IS_DCE4(rdev)) | ||
535 | return; | ||
536 | |||
528 | if (!radeon_encoder->hdmi_offset) { | 537 | if (!radeon_encoder->hdmi_offset) { |
529 | dev_err(rdev->dev, "Disabling not enabled HDMI\n"); | 538 | dev_err(rdev->dev, "Disabling not enabled HDMI\n"); |
530 | return; | 539 | return; |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 1fff95505cf5..5673665ff216 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -69,16 +69,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
69 | struct radeon_i2c_bus_rec i2c; | 69 | struct radeon_i2c_bus_rec i2c; |
70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); | 70 | int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info); |
71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; | 71 | struct _ATOM_GPIO_I2C_INFO *i2c_info; |
72 | uint16_t data_offset; | 72 | uint16_t data_offset, size; |
73 | int i; | 73 | int i, num_indices; |
74 | 74 | ||
75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | 75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); |
76 | i2c.valid = false; | 76 | i2c.valid = false; |
77 | 77 | ||
78 | if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { | 78 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); |
80 | 80 | ||
81 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 81 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
82 | sizeof(ATOM_GPIO_I2C_ASSIGMENT); | ||
83 | |||
84 | for (i = 0; i < num_indices; i++) { | ||
82 | gpio = &i2c_info->asGPIO_Info[i]; | 85 | gpio = &i2c_info->asGPIO_Info[i]; |
83 | 86 | ||
84 | if (gpio->sucI2cId.ucAccess == id) { | 87 | if (gpio->sucI2cId.ucAccess == id) { |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 2becdeda68a3..37db8adb2748 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -760,7 +760,9 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct | |||
760 | dac = RBIOS8(dac_info + 0x3) & 0xf; | 760 | dac = RBIOS8(dac_info + 0x3) & 0xf; |
761 | p_dac->ps2_pdac_adj = (bg << 8) | (dac); | 761 | p_dac->ps2_pdac_adj = (bg << 8) | (dac); |
762 | } | 762 | } |
763 | found = 1; | 763 | /* if the values are all zeros, use the table */ |
764 | if (p_dac->ps2_pdac_adj) | ||
765 | found = 1; | ||
764 | } | 766 | } |
765 | 767 | ||
766 | if (!found) /* fallback to defaults */ | 768 | if (!found) /* fallback to defaults */ |
@@ -895,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
895 | bg = RBIOS8(dac_info + 0x10) & 0xf; | 897 | bg = RBIOS8(dac_info + 0x10) & 0xf; |
896 | dac = RBIOS8(dac_info + 0x11) & 0xf; | 898 | dac = RBIOS8(dac_info + 0x11) & 0xf; |
897 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 899 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
898 | found = 1; | 900 | /* if the values are all zeros, use the table */ |
901 | if (tv_dac->ps2_tvdac_adj) | ||
902 | found = 1; | ||
899 | } else if (rev > 1) { | 903 | } else if (rev > 1) { |
900 | bg = RBIOS8(dac_info + 0xc) & 0xf; | 904 | bg = RBIOS8(dac_info + 0xc) & 0xf; |
901 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; | 905 | dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; |
@@ -908,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
908 | bg = RBIOS8(dac_info + 0xe) & 0xf; | 912 | bg = RBIOS8(dac_info + 0xe) & 0xf; |
909 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; | 913 | dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf; |
910 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); | 914 | tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); |
911 | found = 1; | 915 | /* if the values are all zeros, use the table */ |
916 | if (tv_dac->ps2_tvdac_adj) | ||
917 | found = 1; | ||
912 | } | 918 | } |
913 | tv_dac->tv_std = radeon_combios_get_tv_info(rdev); | 919 | tv_dac->tv_std = radeon_combios_get_tv_info(rdev); |
914 | } | 920 | } |
@@ -925,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
925 | (bg << 16) | (dac << 20); | 931 | (bg << 16) | (dac << 20); |
926 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 932 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
927 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 933 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
928 | found = 1; | 934 | /* if the values are all zeros, use the table */ |
935 | if (tv_dac->ps2_tvdac_adj) | ||
936 | found = 1; | ||
929 | } else { | 937 | } else { |
930 | bg = RBIOS8(dac_info + 0x4) & 0xf; | 938 | bg = RBIOS8(dac_info + 0x4) & 0xf; |
931 | dac = RBIOS8(dac_info + 0x5) & 0xf; | 939 | dac = RBIOS8(dac_info + 0x5) & 0xf; |
@@ -933,7 +941,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct | |||
933 | (bg << 16) | (dac << 20); | 941 | (bg << 16) | (dac << 20); |
934 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; | 942 | tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj; |
935 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; | 943 | tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; |
936 | found = 1; | 944 | /* if the values are all zeros, use the table */ |
945 | if (tv_dac->ps2_tvdac_adj) | ||
946 | found = 1; | ||
937 | } | 947 | } |
938 | } else { | 948 | } else { |
939 | DRM_INFO("No TV DAC info found in BIOS\n"); | 949 | DRM_INFO("No TV DAC info found in BIOS\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 60d59816b94f..1331351c5178 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, | |||
162 | { | 162 | { |
163 | struct drm_device *dev = connector->dev; | 163 | struct drm_device *dev = connector->dev; |
164 | struct drm_connector *conflict; | 164 | struct drm_connector *conflict; |
165 | struct radeon_connector *radeon_conflict; | ||
165 | int i; | 166 | int i; |
166 | 167 | ||
167 | list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { | 168 | list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { |
168 | if (conflict == connector) | 169 | if (conflict == connector) |
169 | continue; | 170 | continue; |
170 | 171 | ||
172 | radeon_conflict = to_radeon_connector(conflict); | ||
171 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 173 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
172 | if (conflict->encoder_ids[i] == 0) | 174 | if (conflict->encoder_ids[i] == 0) |
173 | break; | 175 | break; |
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, | |||
177 | if (conflict->status != connector_status_connected) | 179 | if (conflict->status != connector_status_connected) |
178 | continue; | 180 | continue; |
179 | 181 | ||
182 | if (radeon_conflict->use_digital) | ||
183 | continue; | ||
184 | |||
180 | if (priority == true) { | 185 | if (priority == true) { |
181 | DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); | 186 | DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); |
182 | DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); | 187 | DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); |
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
287 | 292 | ||
288 | if (property == rdev->mode_info.coherent_mode_property) { | 293 | if (property == rdev->mode_info.coherent_mode_property) { |
289 | struct radeon_encoder_atom_dig *dig; | 294 | struct radeon_encoder_atom_dig *dig; |
295 | bool new_coherent_mode; | ||
290 | 296 | ||
291 | /* need to find digital encoder on connector */ | 297 | /* need to find digital encoder on connector */ |
292 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); | 298 | encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); |
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
299 | return 0; | 305 | return 0; |
300 | 306 | ||
301 | dig = radeon_encoder->enc_priv; | 307 | dig = radeon_encoder->enc_priv; |
302 | dig->coherent_mode = val ? true : false; | 308 | new_coherent_mode = val ? true : false; |
303 | radeon_property_change_mode(&radeon_encoder->base); | 309 | if (dig->coherent_mode != new_coherent_mode) { |
310 | dig->coherent_mode = new_coherent_mode; | ||
311 | radeon_property_change_mode(&radeon_encoder->base); | ||
312 | } | ||
304 | } | 313 | } |
305 | 314 | ||
306 | if (property == rdev->mode_info.tv_std_property) { | 315 | if (property == rdev->mode_info.tv_std_property) { |
@@ -315,7 +324,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr | |||
315 | radeon_encoder = to_radeon_encoder(encoder); | 324 | radeon_encoder = to_radeon_encoder(encoder); |
316 | if (!radeon_encoder->enc_priv) | 325 | if (!radeon_encoder->enc_priv) |
317 | return 0; | 326 | return 0; |
318 | if (rdev->is_atom_bios) { | 327 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) { |
319 | struct radeon_encoder_atom_dac *dac_int; | 328 | struct radeon_encoder_atom_dac *dac_int; |
320 | dac_int = radeon_encoder->enc_priv; | 329 | dac_int = radeon_encoder->enc_priv; |
321 | dac_int->tv_std = val; | 330 | dac_int->tv_std = val; |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index dc6eba6b96dd..419630dd2075 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv) | |||
417 | return -EBUSY; | 417 | return -EBUSY; |
418 | } | 418 | } |
419 | 419 | ||
420 | static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | 420 | static void radeon_init_pipes(struct drm_device *dev) |
421 | { | 421 | { |
422 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
422 | uint32_t gb_tile_config, gb_pipe_sel = 0; | 423 | uint32_t gb_tile_config, gb_pipe_sel = 0; |
423 | 424 | ||
424 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { | 425 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { |
@@ -436,11 +437,12 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
436 | dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; | 437 | dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; |
437 | } else { | 438 | } else { |
438 | /* R3xx */ | 439 | /* R3xx */ |
439 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || | 440 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 && |
441 | dev->pdev->device != 0x4144) || | ||
440 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { | 442 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { |
441 | dev_priv->num_gb_pipes = 2; | 443 | dev_priv->num_gb_pipes = 2; |
442 | } else { | 444 | } else { |
443 | /* R3Vxx */ | 445 | /* RV3xx/R300 AD */ |
444 | dev_priv->num_gb_pipes = 1; | 446 | dev_priv->num_gb_pipes = 1; |
445 | } | 447 | } |
446 | } | 448 | } |
@@ -736,7 +738,7 @@ static int radeon_do_engine_reset(struct drm_device * dev) | |||
736 | 738 | ||
737 | /* setup the raster pipes */ | 739 | /* setup the raster pipes */ |
738 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) | 740 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) |
739 | radeon_init_pipes(dev_priv); | 741 | radeon_init_pipes(dev); |
740 | 742 | ||
741 | /* Reset the CP ring */ | 743 | /* Reset the CP ring */ |
742 | radeon_do_cp_reset(dev_priv); | 744 | radeon_do_cp_reset(dev_priv); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index bddf17f97da8..7b629e305560 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -36,6 +36,54 @@ | |||
36 | #include "radeon.h" | 36 | #include "radeon.h" |
37 | #include "atom.h" | 37 | #include "atom.h" |
38 | 38 | ||
39 | static const char radeon_family_name[][16] = { | ||
40 | "R100", | ||
41 | "RV100", | ||
42 | "RS100", | ||
43 | "RV200", | ||
44 | "RS200", | ||
45 | "R200", | ||
46 | "RV250", | ||
47 | "RS300", | ||
48 | "RV280", | ||
49 | "R300", | ||
50 | "R350", | ||
51 | "RV350", | ||
52 | "RV380", | ||
53 | "R420", | ||
54 | "R423", | ||
55 | "RV410", | ||
56 | "RS400", | ||
57 | "RS480", | ||
58 | "RS600", | ||
59 | "RS690", | ||
60 | "RS740", | ||
61 | "RV515", | ||
62 | "R520", | ||
63 | "RV530", | ||
64 | "RV560", | ||
65 | "RV570", | ||
66 | "R580", | ||
67 | "R600", | ||
68 | "RV610", | ||
69 | "RV630", | ||
70 | "RV670", | ||
71 | "RV620", | ||
72 | "RV635", | ||
73 | "RS780", | ||
74 | "RS880", | ||
75 | "RV770", | ||
76 | "RV730", | ||
77 | "RV710", | ||
78 | "RV740", | ||
79 | "CEDAR", | ||
80 | "REDWOOD", | ||
81 | "JUNIPER", | ||
82 | "CYPRESS", | ||
83 | "HEMLOCK", | ||
84 | "LAST", | ||
85 | }; | ||
86 | |||
39 | /* | 87 | /* |
40 | * Clear GPU surface registers. | 88 | * Clear GPU surface registers. |
41 | */ | 89 | */ |
@@ -526,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev, | |||
526 | int r; | 574 | int r; |
527 | int dma_bits; | 575 | int dma_bits; |
528 | 576 | ||
529 | DRM_INFO("radeon: Initializing kernel modesetting.\n"); | ||
530 | rdev->shutdown = false; | 577 | rdev->shutdown = false; |
531 | rdev->dev = &pdev->dev; | 578 | rdev->dev = &pdev->dev; |
532 | rdev->ddev = ddev; | 579 | rdev->ddev = ddev; |
@@ -538,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
538 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 585 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
539 | rdev->gpu_lockup = false; | 586 | rdev->gpu_lockup = false; |
540 | rdev->accel_working = false; | 587 | rdev->accel_working = false; |
588 | |||
589 | DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", | ||
590 | radeon_family_name[rdev->family], pdev->vendor, pdev->device); | ||
591 | |||
541 | /* mutex initialization are all done here so we | 592 | /* mutex initialization are all done here so we |
542 | * can recall function without having locking issues */ | 593 | * can recall function without having locking issues */ |
543 | mutex_init(&rdev->cs_mutex); | 594 | mutex_init(&rdev->cs_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 055a51732dcb..4b05563d99e1 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -43,9 +43,10 @@ | |||
43 | * - 2.0.0 - initial interface | 43 | * - 2.0.0 - initial interface |
44 | * - 2.1.0 - add square tiling interface | 44 | * - 2.1.0 - add square tiling interface |
45 | * - 2.2.0 - add r6xx/r7xx const buffer support | 45 | * - 2.2.0 - add r6xx/r7xx const buffer support |
46 | * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs | ||
46 | */ | 47 | */ |
47 | #define KMS_DRIVER_MAJOR 2 | 48 | #define KMS_DRIVER_MAJOR 2 |
48 | #define KMS_DRIVER_MINOR 2 | 49 | #define KMS_DRIVER_MINOR 3 |
49 | #define KMS_DRIVER_PATCHLEVEL 0 | 50 | #define KMS_DRIVER_PATCHLEVEL 0 |
50 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 51 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
51 | int radeon_driver_unload_kms(struct drm_device *dev); | 52 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 52d6f96f274b..30293bec0801 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -317,12 +317,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
317 | struct radeon_device *rdev = dev->dev_private; | 317 | struct radeon_device *rdev = dev->dev_private; |
318 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 318 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
319 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; | 319 | DAC_ENCODER_CONTROL_PS_ALLOCATION args; |
320 | int index = 0, num = 0; | 320 | int index = 0; |
321 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | 321 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
322 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
323 | |||
324 | if (dac_info->tv_std) | ||
325 | tv_std = dac_info->tv_std; | ||
326 | 322 | ||
327 | memset(&args, 0, sizeof(args)); | 323 | memset(&args, 0, sizeof(args)); |
328 | 324 | ||
@@ -330,12 +326,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
330 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 326 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
331 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: | 327 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
332 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); | 328 | index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); |
333 | num = 1; | ||
334 | break; | 329 | break; |
335 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 330 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
336 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 331 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
337 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); | 332 | index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); |
338 | num = 2; | ||
339 | break; | 333 | break; |
340 | } | 334 | } |
341 | 335 | ||
@@ -346,7 +340,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) | |||
346 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | 340 | else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
347 | args.ucDacStandard = ATOM_DAC1_CV; | 341 | args.ucDacStandard = ATOM_DAC1_CV; |
348 | else { | 342 | else { |
349 | switch (tv_std) { | 343 | switch (dac_info->tv_std) { |
350 | case TV_STD_PAL: | 344 | case TV_STD_PAL: |
351 | case TV_STD_PAL_M: | 345 | case TV_STD_PAL_M: |
352 | case TV_STD_SCART_PAL: | 346 | case TV_STD_SCART_PAL: |
@@ -377,10 +371,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
377 | TV_ENCODER_CONTROL_PS_ALLOCATION args; | 371 | TV_ENCODER_CONTROL_PS_ALLOCATION args; |
378 | int index = 0; | 372 | int index = 0; |
379 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; | 373 | struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
380 | enum radeon_tv_std tv_std = TV_STD_NTSC; | ||
381 | |||
382 | if (dac_info->tv_std) | ||
383 | tv_std = dac_info->tv_std; | ||
384 | 374 | ||
385 | memset(&args, 0, sizeof(args)); | 375 | memset(&args, 0, sizeof(args)); |
386 | 376 | ||
@@ -391,7 +381,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
391 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) | 381 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
392 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; | 382 | args.sTVEncoder.ucTvStandard = ATOM_TV_CV; |
393 | else { | 383 | else { |
394 | switch (tv_std) { | 384 | switch (dac_info->tv_std) { |
395 | case TV_STD_NTSC: | 385 | case TV_STD_NTSC: |
396 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; | 386 | args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; |
397 | break; | 387 | break; |
@@ -875,6 +865,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
875 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 865 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
876 | if (dig->coherent_mode) | 866 | if (dig->coherent_mode) |
877 | args.v3.acConfig.fCoherentMode = 1; | 867 | args.v3.acConfig.fCoherentMode = 1; |
868 | if (radeon_encoder->pixel_clock > 165000) | ||
869 | args.v3.acConfig.fDualLinkConnector = 1; | ||
878 | } | 870 | } |
879 | } else if (ASIC_IS_DCE32(rdev)) { | 871 | } else if (ASIC_IS_DCE32(rdev)) { |
880 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | 872 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; |
@@ -898,6 +890,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
898 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 890 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
899 | if (dig->coherent_mode) | 891 | if (dig->coherent_mode) |
900 | args.v2.acConfig.fCoherentMode = 1; | 892 | args.v2.acConfig.fCoherentMode = 1; |
893 | if (radeon_encoder->pixel_clock > 165000) | ||
894 | args.v2.acConfig.fDualLinkConnector = 1; | ||
901 | } | 895 | } |
902 | } else { | 896 | } else { |
903 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 897 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
@@ -1383,8 +1377,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1383 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1377 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
1384 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: | 1378 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
1385 | atombios_dac_setup(encoder, ATOM_ENABLE); | 1379 | atombios_dac_setup(encoder, ATOM_ENABLE); |
1386 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 1380 | if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { |
1387 | atombios_tv_setup(encoder, ATOM_ENABLE); | 1381 | if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1382 | atombios_tv_setup(encoder, ATOM_ENABLE); | ||
1383 | else | ||
1384 | atombios_tv_setup(encoder, ATOM_DISABLE); | ||
1385 | } | ||
1388 | break; | 1386 | break; |
1389 | } | 1387 | } |
1390 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1388 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
@@ -1558,12 +1556,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = { | |||
1558 | struct radeon_encoder_atom_dac * | 1556 | struct radeon_encoder_atom_dac * |
1559 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | 1557 | radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) |
1560 | { | 1558 | { |
1559 | struct drm_device *dev = radeon_encoder->base.dev; | ||
1560 | struct radeon_device *rdev = dev->dev_private; | ||
1561 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); | 1561 | struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); |
1562 | 1562 | ||
1563 | if (!dac) | 1563 | if (!dac) |
1564 | return NULL; | 1564 | return NULL; |
1565 | 1565 | ||
1566 | dac->tv_std = TV_STD_NTSC; | 1566 | dac->tv_std = radeon_atombios_get_tv_info(rdev); |
1567 | return dac; | 1567 | return dac; |
1568 | } | 1568 | } |
1569 | 1569 | ||
@@ -1641,6 +1641,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1641 | break; | 1641 | break; |
1642 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: | 1642 | case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
1643 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); | 1643 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); |
1644 | radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); | ||
1644 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); | 1645 | drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); |
1645 | break; | 1646 | break; |
1646 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: | 1647 | case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 93c7d5d41914..e329066dcabd 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
@@ -36,7 +36,7 @@ | |||
36 | * Radeon chip families | 36 | * Radeon chip families |
37 | */ | 37 | */ |
38 | enum radeon_family { | 38 | enum radeon_family { |
39 | CHIP_R100, | 39 | CHIP_R100 = 0, |
40 | CHIP_RV100, | 40 | CHIP_RV100, |
41 | CHIP_RS100, | 41 | CHIP_RS100, |
42 | CHIP_RV200, | 42 | CHIP_RV200, |
@@ -99,4 +99,5 @@ enum radeon_chip_flags { | |||
99 | RADEON_IS_PCI = 0x00800000UL, | 99 | RADEON_IS_PCI = 0x00800000UL, |
100 | RADEON_IS_IGPGART = 0x01000000UL, | 100 | RADEON_IS_IGPGART = 0x01000000UL, |
101 | }; | 101 | }; |
102 | |||
102 | #endif | 103 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index cf389ce50a8a..2441cca7d775 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -830,8 +830,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) | |||
830 | crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; | 830 | crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; |
831 | 831 | ||
832 | if (rdev->family == CHIP_R420 || | 832 | if (rdev->family == CHIP_R420 || |
833 | rdev->family == CHIP_R423 || | 833 | rdev->family == CHIP_R423 || |
834 | rdev->family == CHIP_RV410) | 834 | rdev->family == CHIP_RV410) |
835 | tv_dac_cntl |= (R420_TV_DAC_RDACPD | | 835 | tv_dac_cntl |= (R420_TV_DAC_RDACPD | |
836 | R420_TV_DAC_GDACPD | | 836 | R420_TV_DAC_GDACPD | |
837 | R420_TV_DAC_BDACPD | | 837 | R420_TV_DAC_BDACPD | |
@@ -907,35 +907,43 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, | |||
907 | if (rdev->family != CHIP_R200) { | 907 | if (rdev->family != CHIP_R200) { |
908 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); | 908 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
909 | if (rdev->family == CHIP_R420 || | 909 | if (rdev->family == CHIP_R420 || |
910 | rdev->family == CHIP_R423 || | 910 | rdev->family == CHIP_R423 || |
911 | rdev->family == CHIP_RV410) { | 911 | rdev->family == CHIP_RV410) { |
912 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | | 912 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | |
913 | RADEON_TV_DAC_BGADJ_MASK | | 913 | RADEON_TV_DAC_BGADJ_MASK | |
914 | R420_TV_DAC_DACADJ_MASK | | 914 | R420_TV_DAC_DACADJ_MASK | |
915 | R420_TV_DAC_RDACPD | | 915 | R420_TV_DAC_RDACPD | |
916 | R420_TV_DAC_GDACPD | | 916 | R420_TV_DAC_GDACPD | |
917 | R420_TV_DAC_BDACPD | | 917 | R420_TV_DAC_BDACPD | |
918 | R420_TV_DAC_TVENABLE); | 918 | R420_TV_DAC_TVENABLE); |
919 | } else { | 919 | } else { |
920 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | | 920 | tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | |
921 | RADEON_TV_DAC_BGADJ_MASK | | 921 | RADEON_TV_DAC_BGADJ_MASK | |
922 | RADEON_TV_DAC_DACADJ_MASK | | 922 | RADEON_TV_DAC_DACADJ_MASK | |
923 | RADEON_TV_DAC_RDACPD | | 923 | RADEON_TV_DAC_RDACPD | |
924 | RADEON_TV_DAC_GDACPD | | 924 | RADEON_TV_DAC_GDACPD | |
925 | RADEON_TV_DAC_BDACPD); | 925 | RADEON_TV_DAC_BDACPD); |
926 | } | 926 | } |
927 | 927 | ||
928 | /* FIXME TV */ | 928 | tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; |
929 | if (tv_dac) { | 929 | |
930 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; | 930 | if (is_tv) { |
931 | tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | | 931 | if (tv_dac->tv_std == TV_STD_NTSC || |
932 | RADEON_TV_DAC_NHOLD | | 932 | tv_dac->tv_std == TV_STD_NTSC_J || |
933 | RADEON_TV_DAC_STD_PS2 | | 933 | tv_dac->tv_std == TV_STD_PAL_M || |
934 | tv_dac->ps2_tvdac_adj); | 934 | tv_dac->tv_std == TV_STD_PAL_60) |
935 | tv_dac_cntl |= tv_dac->ntsc_tvdac_adj; | ||
936 | else | ||
937 | tv_dac_cntl |= tv_dac->pal_tvdac_adj; | ||
938 | |||
939 | if (tv_dac->tv_std == TV_STD_NTSC || | ||
940 | tv_dac->tv_std == TV_STD_NTSC_J) | ||
941 | tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; | ||
942 | else | ||
943 | tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; | ||
935 | } else | 944 | } else |
936 | tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | | 945 | tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 | |
937 | RADEON_TV_DAC_NHOLD | | 946 | tv_dac->ps2_tvdac_adj); |
938 | RADEON_TV_DAC_STD_PS2); | ||
939 | 947 | ||
940 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); | 948 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
941 | } | 949 | } |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 19c4663fa9c6..1e97b2d129fd 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 | |||
@@ -125,6 +125,8 @@ r300 0x4f60 | |||
125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 | 125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 |
126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 | 126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 |
127 | 0x4008 GB_ENABLE | 127 | 0x4008 GB_ENABLE |
128 | 0x4010 GB_MSPOS0 | ||
129 | 0x4014 GB_MSPOS1 | ||
128 | 0x401C GB_SELECT | 130 | 0x401C GB_SELECT |
129 | 0x4020 GB_AA_CONFIG | 131 | 0x4020 GB_AA_CONFIG |
130 | 0x4024 GB_FIFO_SIZE | 132 | 0x4024 GB_FIFO_SIZE |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 989f7a020832..e958980d00f1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 | |||
@@ -125,6 +125,8 @@ r420 0x4f60 | |||
125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 | 125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 |
126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 | 126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 |
127 | 0x4008 GB_ENABLE | 127 | 0x4008 GB_ENABLE |
128 | 0x4010 GB_MSPOS0 | ||
129 | 0x4014 GB_MSPOS1 | ||
128 | 0x401C GB_SELECT | 130 | 0x401C GB_SELECT |
129 | 0x4020 GB_AA_CONFIG | 131 | 0x4020 GB_AA_CONFIG |
130 | 0x4024 GB_FIFO_SIZE | 132 | 0x4024 GB_FIFO_SIZE |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 6801b865d1c4..83e8bc0c2bb2 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 | |||
@@ -125,6 +125,8 @@ rs600 0x6d40 | |||
125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 | 125 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 |
126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 | 126 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 |
127 | 0x4008 GB_ENABLE | 127 | 0x4008 GB_ENABLE |
128 | 0x4010 GB_MSPOS0 | ||
129 | 0x4014 GB_MSPOS1 | ||
128 | 0x401C GB_SELECT | 130 | 0x401C GB_SELECT |
129 | 0x4020 GB_AA_CONFIG | 131 | 0x4020 GB_AA_CONFIG |
130 | 0x4024 GB_FIFO_SIZE | 132 | 0x4024 GB_FIFO_SIZE |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 38abf63bf2cd..1e46233985eb 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
@@ -35,6 +35,7 @@ rv515 0x6d40 | |||
35 | 0x1DA8 VAP_VPORT_ZSCALE | 35 | 0x1DA8 VAP_VPORT_ZSCALE |
36 | 0x1DAC VAP_VPORT_ZOFFSET | 36 | 0x1DAC VAP_VPORT_ZOFFSET |
37 | 0x2080 VAP_CNTL | 37 | 0x2080 VAP_CNTL |
38 | 0x208C VAP_INDEX_OFFSET | ||
38 | 0x2090 VAP_OUT_VTX_FMT_0 | 39 | 0x2090 VAP_OUT_VTX_FMT_0 |
39 | 0x2094 VAP_OUT_VTX_FMT_1 | 40 | 0x2094 VAP_OUT_VTX_FMT_1 |
40 | 0x20B0 VAP_VTE_CNTL | 41 | 0x20B0 VAP_VTE_CNTL |
@@ -158,6 +159,8 @@ rv515 0x6d40 | |||
158 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 | 159 | 0x4000 GB_VAP_RASTER_VTX_FMT_0 |
159 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 | 160 | 0x4004 GB_VAP_RASTER_VTX_FMT_1 |
160 | 0x4008 GB_ENABLE | 161 | 0x4008 GB_ENABLE |
162 | 0x4010 GB_MSPOS0 | ||
163 | 0x4014 GB_MSPOS1 | ||
161 | 0x401C GB_SELECT | 164 | 0x401C GB_SELECT |
162 | 0x4020 GB_AA_CONFIG | 165 | 0x4020 GB_AA_CONFIG |
163 | 0x4024 GB_FIFO_SIZE | 166 | 0x4024 GB_FIFO_SIZE |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index abf824c2123d..a81bc7a21e14 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -159,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) | |||
159 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); | 159 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
160 | 160 | ||
161 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 161 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
162 | tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); | 162 | tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1); |
163 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); | 163 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
164 | 164 | ||
165 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); | 165 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index c1605b528e8f..0f28d91f29d8 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = { | |||
142 | "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", | 142 | "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S", |
143 | "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", | 143 | "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S", |
144 | NULL }, | 144 | NULL }, |
145 | /* Set 17: iMac 9,1 */ | ||
146 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P", | ||
147 | "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL }, | ||
148 | /* Set 18: MacBook Pro 2,2 */ | ||
149 | { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0", | ||
150 | "Th0H", "Th1H", "Tm0P", "Ts0P", NULL }, | ||
145 | }; | 151 | }; |
146 | 152 | ||
147 | /* List of keys used to read/write fan speeds */ | 153 | /* List of keys used to read/write fan speeds */ |
@@ -1350,6 +1356,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1350 | { .accelerometer = 1, .light = 1, .temperature_set = 15 }, | 1356 | { .accelerometer = 1, .light = 1, .temperature_set = 15 }, |
1351 | /* MacPro3,1: temperature set 16 */ | 1357 | /* MacPro3,1: temperature set 16 */ |
1352 | { .accelerometer = 0, .light = 0, .temperature_set = 16 }, | 1358 | { .accelerometer = 0, .light = 0, .temperature_set = 16 }, |
1359 | /* iMac 9,1: light sensor only, temperature set 17 */ | ||
1360 | { .accelerometer = 0, .light = 0, .temperature_set = 17 }, | ||
1361 | /* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */ | ||
1362 | { .accelerometer = 1, .light = 1, .temperature_set = 18 }, | ||
1353 | }; | 1363 | }; |
1354 | 1364 | ||
1355 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1365 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
@@ -1375,6 +1385,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1375 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1385 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1376 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, | 1386 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, |
1377 | &applesmc_dmi_data[9]}, | 1387 | &applesmc_dmi_data[9]}, |
1388 | { applesmc_dmi_match, "Apple MacBook Pro 2,2", { | ||
1389 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."), | ||
1390 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") }, | ||
1391 | &applesmc_dmi_data[18]}, | ||
1378 | { applesmc_dmi_match, "Apple MacBook Pro", { | 1392 | { applesmc_dmi_match, "Apple MacBook Pro", { |
1379 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1393 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1380 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, | 1394 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, |
@@ -1415,6 +1429,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1415 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1429 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1416 | DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, | 1430 | DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") }, |
1417 | &applesmc_dmi_data[4]}, | 1431 | &applesmc_dmi_data[4]}, |
1432 | { applesmc_dmi_match, "Apple iMac 9,1", { | ||
1433 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."), | ||
1434 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") }, | ||
1435 | &applesmc_dmi_data[17]}, | ||
1418 | { applesmc_dmi_match, "Apple iMac 8", { | 1436 | { applesmc_dmi_match, "Apple iMac 8", { |
1419 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1437 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1420 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, | 1438 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 1002befd87d5..5be09c048c5f 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -539,14 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
539 | 539 | ||
540 | struct it87_data *data = dev_get_drvdata(dev); | 540 | struct it87_data *data = dev_get_drvdata(dev); |
541 | long val; | 541 | long val; |
542 | u8 reg; | ||
542 | 543 | ||
543 | if (strict_strtol(buf, 10, &val) < 0) | 544 | if (strict_strtol(buf, 10, &val) < 0) |
544 | return -EINVAL; | 545 | return -EINVAL; |
545 | 546 | ||
546 | mutex_lock(&data->update_lock); | 547 | reg = it87_read_value(data, IT87_REG_TEMP_ENABLE); |
547 | 548 | reg &= ~(1 << nr); | |
548 | data->sensor &= ~(1 << nr); | 549 | reg &= ~(8 << nr); |
549 | data->sensor &= ~(8 << nr); | ||
550 | if (val == 2) { /* backwards compatibility */ | 550 | if (val == 2) { /* backwards compatibility */ |
551 | dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " | 551 | dev_warn(dev, "Sensor type 2 is deprecated, please use 4 " |
552 | "instead\n"); | 552 | "instead\n"); |
@@ -554,14 +554,16 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr, | |||
554 | } | 554 | } |
555 | /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ | 555 | /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ |
556 | if (val == 3) | 556 | if (val == 3) |
557 | data->sensor |= 1 << nr; | 557 | reg |= 1 << nr; |
558 | else if (val == 4) | 558 | else if (val == 4) |
559 | data->sensor |= 8 << nr; | 559 | reg |= 8 << nr; |
560 | else if (val != 0) { | 560 | else if (val != 0) |
561 | mutex_unlock(&data->update_lock); | ||
562 | return -EINVAL; | 561 | return -EINVAL; |
563 | } | 562 | |
563 | mutex_lock(&data->update_lock); | ||
564 | data->sensor = reg; | ||
564 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); | 565 | it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor); |
566 | data->valid = 0; /* Force cache refresh */ | ||
565 | mutex_unlock(&data->update_lock); | 567 | mutex_unlock(&data->update_lock); |
566 | return count; | 568 | return count; |
567 | } | 569 | } |
@@ -1841,14 +1843,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1841 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); | 1843 | it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127); |
1842 | } | 1844 | } |
1843 | 1845 | ||
1844 | /* Check if temperature channels are reset manually or by some reason */ | 1846 | /* Temperature channels are not forcibly enabled, as they can be |
1845 | tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE); | 1847 | * set to two different sensor types and we can't guess which one |
1846 | if ((tmp & 0x3f) == 0) { | 1848 | * is correct for a given system. These channels can be enabled at |
1847 | /* Temp1,Temp3=thermistor; Temp2=thermal diode */ | 1849 | * run-time through the temp{1-3}_type sysfs accessors if needed. */ |
1848 | tmp = (tmp & 0xc0) | 0x2a; | ||
1849 | it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp); | ||
1850 | } | ||
1851 | data->sensor = tmp; | ||
1852 | 1850 | ||
1853 | /* Check if voltage monitors are reset manually or by some reason */ | 1851 | /* Check if voltage monitors are reset manually or by some reason */ |
1854 | tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); | 1852 | tmp = it87_read_value(data, IT87_REG_VIN_ENABLE); |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 6b2d8ae64fe1..a610e7880fb3 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
@@ -303,13 +303,13 @@ error_ret: | |||
303 | **/ | 303 | **/ |
304 | static inline int sht15_calc_temp(struct sht15_data *data) | 304 | static inline int sht15_calc_temp(struct sht15_data *data) |
305 | { | 305 | { |
306 | int d1 = 0; | 306 | int d1 = temppoints[0].d1; |
307 | int i; | 307 | int i; |
308 | 308 | ||
309 | for (i = 1; i < ARRAY_SIZE(temppoints); i++) | 309 | for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--) |
310 | /* Find pointer to interpolate */ | 310 | /* Find pointer to interpolate */ |
311 | if (data->supply_uV > temppoints[i - 1].vdd) { | 311 | if (data->supply_uV > temppoints[i - 1].vdd) { |
312 | d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) | 312 | d1 = (data->supply_uV - temppoints[i - 1].vdd) |
313 | * (temppoints[i].d1 - temppoints[i - 1].d1) | 313 | * (temppoints[i].d1 - temppoints[i - 1].d1) |
314 | / (temppoints[i].vdd - temppoints[i - 1].vdd) | 314 | / (temppoints[i].vdd - temppoints[i - 1].vdd) |
315 | + temppoints[i - 1].d1; | 315 | + temppoints[i - 1].d1; |
@@ -542,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
542 | /* If a regulator is available, query what the supply voltage actually is!*/ | 542 | /* If a regulator is available, query what the supply voltage actually is!*/ |
543 | data->reg = regulator_get(data->dev, "vcc"); | 543 | data->reg = regulator_get(data->dev, "vcc"); |
544 | if (!IS_ERR(data->reg)) { | 544 | if (!IS_ERR(data->reg)) { |
545 | data->supply_uV = regulator_get_voltage(data->reg); | 545 | int voltage; |
546 | |||
547 | voltage = regulator_get_voltage(data->reg); | ||
548 | if (voltage) | ||
549 | data->supply_uV = voltage; | ||
550 | |||
546 | regulator_enable(data->reg); | 551 | regulator_enable(data->reg); |
547 | /* setup a notifier block to update this if another device | 552 | /* setup a notifier block to update this if another device |
548 | * causes the voltage to change */ | 553 | * causes the voltage to change */ |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index a4046e94158d..f9daffd7d0e3 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -264,8 +264,8 @@ void ide_retry_pc(ide_drive_t *drive) | |||
264 | * of it. The failed command will be retried after sense data | 264 | * of it. The failed command will be retried after sense data |
265 | * is acquired. | 265 | * is acquired. |
266 | */ | 266 | */ |
267 | blk_requeue_request(failed_rq->q, failed_rq); | ||
268 | drive->hwif->rq = NULL; | 267 | drive->hwif->rq = NULL; |
268 | ide_requeue_and_plug(drive, failed_rq); | ||
269 | if (ide_queue_sense_rq(drive, pc)) { | 269 | if (ide_queue_sense_rq(drive, pc)) { |
270 | blk_start_request(failed_rq); | 270 | blk_start_request(failed_rq); |
271 | ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq)); | 271 | ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq)); |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 2c17e3fb43e3..06b14bc9a1d4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -493,6 +493,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
493 | if (rq) { | 493 | if (rq) { |
494 | hwif->rq = NULL; | 494 | hwif->rq = NULL; |
495 | rq->errors = 0; | 495 | rq->errors = 0; |
496 | ide_requeue_and_plug(drive, rq); | ||
496 | } | 497 | } |
497 | return ret; | 498 | return ret; |
498 | } | 499 | } |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index db96138fefcd..172ac9218154 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -566,7 +566,7 @@ plug_device_2: | |||
566 | blk_plug_device(q); | 566 | blk_plug_device(q); |
567 | } | 567 | } |
568 | 568 | ||
569 | static void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) | 569 | void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) |
570 | { | 570 | { |
571 | struct request_queue *q = drive->queue; | 571 | struct request_queue *q = drive->queue; |
572 | unsigned long flags; | 572 | unsigned long flags; |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index cc8633cbe133..67fb73559fd5 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -428,13 +428,11 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, | |||
428 | { | 428 | { |
429 | struct request *rq; | 429 | struct request *rq; |
430 | int error; | 430 | int error; |
431 | int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE; | ||
431 | 432 | ||
432 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 433 | rq = blk_get_request(drive->queue, rw, __GFP_WAIT); |
433 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 434 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
434 | 435 | ||
435 | if (cmd->tf_flags & IDE_TFLAG_WRITE) | ||
436 | rq->cmd_flags |= REQ_RW; | ||
437 | |||
438 | /* | 436 | /* |
439 | * (ks) We transfer currently only whole sectors. | 437 | * (ks) We transfer currently only whole sectors. |
440 | * This is suffient for now. But, it would be great, | 438 | * This is suffient for now. But, it would be great, |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index fc73d6ac11b6..ad63b79afac1 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -3694,7 +3694,7 @@ static void cm_add_one(struct ib_device *ib_device) | |||
3694 | cm_dev->device = device_create(&cm_class, &ib_device->dev, | 3694 | cm_dev->device = device_create(&cm_class, &ib_device->dev, |
3695 | MKDEV(0, 0), NULL, | 3695 | MKDEV(0, 0), NULL, |
3696 | "%s", ib_device->name); | 3696 | "%s", ib_device->name); |
3697 | if (!cm_dev->device) { | 3697 | if (IS_ERR(cm_dev->device)) { |
3698 | kfree(cm_dev); | 3698 | kfree(cm_dev); |
3699 | return; | 3699 | return; |
3700 | } | 3700 | } |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 7794249430ca..6d777069d86d 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -1684,6 +1684,7 @@ int rdma_set_ib_paths(struct rdma_cm_id *id, | |||
1684 | } | 1684 | } |
1685 | 1685 | ||
1686 | memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths); | 1686 | memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths); |
1687 | id->route.num_paths = num_paths; | ||
1687 | return 0; | 1688 | return 0; |
1688 | err: | 1689 | err: |
1689 | cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED); | 1690 | cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED); |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 56147b28a23a..1d27b9a8e2d6 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -240,7 +240,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device | |||
240 | mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev, | 240 | mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev, |
241 | size, &mfrpl->map, | 241 | size, &mfrpl->map, |
242 | GFP_KERNEL); | 242 | GFP_KERNEL); |
243 | if (!mfrpl->ibfrpl.page_list) | 243 | if (!mfrpl->mapped_page_list) |
244 | goto err_free; | 244 | goto err_free; |
245 | 245 | ||
246 | WARN_ON(mfrpl->map & 0x3f); | 246 | WARN_ON(mfrpl->map & 0x3f); |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 5a076e8f116a..e54f312e4bdc 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -2821,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
2821 | attr->cap.max_send_wr = nesqp->hwqp.sq_size; | 2821 | attr->cap.max_send_wr = nesqp->hwqp.sq_size; |
2822 | attr->cap.max_recv_wr = nesqp->hwqp.rq_size; | 2822 | attr->cap.max_recv_wr = nesqp->hwqp.rq_size; |
2823 | attr->cap.max_recv_sge = 1; | 2823 | attr->cap.max_recv_sge = 1; |
2824 | if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) { | 2824 | if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) |
2825 | init_attr->cap.max_inline_data = 0; | 2825 | attr->cap.max_inline_data = 0; |
2826 | } else { | 2826 | else |
2827 | init_attr->cap.max_inline_data = 64; | 2827 | attr->cap.max_inline_data = 64; |
2828 | } | ||
2829 | 2828 | ||
2830 | init_attr->event_handler = nesqp->ibqp.event_handler; | 2829 | init_attr->event_handler = nesqp->ibqp.event_handler; |
2831 | init_attr->qp_context = nesqp->ibqp.qp_context; | 2830 | init_attr->qp_context = nesqp->ibqp.qp_context; |
diff --git a/drivers/input/input.c b/drivers/input/input.c index afd4e2b7658c..9c79bd56b51a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -660,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
660 | int input_get_keycode(struct input_dev *dev, | 660 | int input_get_keycode(struct input_dev *dev, |
661 | unsigned int scancode, unsigned int *keycode) | 661 | unsigned int scancode, unsigned int *keycode) |
662 | { | 662 | { |
663 | return dev->getkeycode(dev, scancode, keycode); | 663 | unsigned long flags; |
664 | int retval; | ||
665 | |||
666 | spin_lock_irqsave(&dev->event_lock, flags); | ||
667 | retval = dev->getkeycode(dev, scancode, keycode); | ||
668 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
669 | |||
670 | return retval; | ||
664 | } | 671 | } |
665 | EXPORT_SYMBOL(input_get_keycode); | 672 | EXPORT_SYMBOL(input_get_keycode); |
666 | 673 | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index ffc25cfcef7a..b443e088fd3c 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -374,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev) | |||
374 | input_dev->name = pdev->name; | 374 | input_dev->name = pdev->name; |
375 | input_dev->id.bustype = BUS_HOST; | 375 | input_dev->id.bustype = BUS_HOST; |
376 | input_dev->dev.parent = &pdev->dev; | 376 | input_dev->dev.parent = &pdev->dev; |
377 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 377 | input_dev->evbit[0] = BIT_MASK(EV_KEY); |
378 | if (!pdata->no_autorepeat) | ||
379 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
378 | input_dev->open = matrix_keypad_start; | 380 | input_dev->open = matrix_keypad_start; |
379 | input_dev->close = matrix_keypad_stop; | 381 | input_dev->close = matrix_keypad_stop; |
380 | 382 | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 99d58764ef03..0d22cb9ce42e 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -64,6 +64,7 @@ static const struct alps_model_info alps_model_data[] = { | |||
64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, | 64 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, |
65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, | 65 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, |
66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ | 66 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ |
67 | { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, /* HP Pavilion dm3 */ | ||
67 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, | 68 | { { 0x52, 0x01, 0x14 }, 0xff, 0xff, |
68 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ | 69 | ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ |
69 | }; | 70 | }; |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4f8fe0886b2a..b89879bd860f 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = { | |||
803 | .disconnect = bcm5974_disconnect, | 803 | .disconnect = bcm5974_disconnect, |
804 | .suspend = bcm5974_suspend, | 804 | .suspend = bcm5974_suspend, |
805 | .resume = bcm5974_resume, | 805 | .resume = bcm5974_resume, |
806 | .reset_resume = bcm5974_resume, | ||
807 | .id_table = bcm5974_table, | 806 | .id_table = bcm5974_table, |
808 | .supports_autosuspend = 1, | 807 | .supports_autosuspend = 1, |
809 | }; | 808 | }; |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 577688b5b951..6440a8f55686 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -39,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); | |||
39 | 39 | ||
40 | static bool i8042_nomux; | 40 | static bool i8042_nomux; |
41 | module_param_named(nomux, i8042_nomux, bool, 0); | 41 | module_param_named(nomux, i8042_nomux, bool, 0); |
42 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); | 42 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); |
43 | 43 | ||
44 | static bool i8042_unlock; | 44 | static bool i8042_unlock; |
45 | module_param_named(unlock, i8042_unlock, bool, 0); | 45 | module_param_named(unlock, i8042_unlock, bool, 0); |
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 82ae18d29685..014248344763 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c | |||
@@ -68,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, | |||
68 | unsigned int scancode, | 68 | unsigned int scancode, |
69 | unsigned int *keycode) | 69 | unsigned int *keycode) |
70 | { | 70 | { |
71 | const struct key_entry *key = | 71 | const struct key_entry *key; |
72 | sparse_keymap_entry_from_scancode(dev, scancode); | ||
73 | 72 | ||
74 | if (key && key->type == KE_KEY) { | 73 | if (dev->keycode) { |
75 | *keycode = key->keycode; | 74 | key = sparse_keymap_entry_from_scancode(dev, scancode); |
76 | return 0; | 75 | if (key && key->type == KE_KEY) { |
76 | *keycode = key->keycode; | ||
77 | return 0; | ||
78 | } | ||
77 | } | 79 | } |
78 | 80 | ||
79 | return -EINVAL; | 81 | return -EINVAL; |
@@ -86,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev, | |||
86 | struct key_entry *key; | 88 | struct key_entry *key; |
87 | int old_keycode; | 89 | int old_keycode; |
88 | 90 | ||
89 | if (keycode < 0 || keycode > KEY_MAX) | 91 | if (dev->keycode) { |
90 | return -EINVAL; | 92 | key = sparse_keymap_entry_from_scancode(dev, scancode); |
91 | 93 | if (key && key->type == KE_KEY) { | |
92 | key = sparse_keymap_entry_from_scancode(dev, scancode); | 94 | old_keycode = key->keycode; |
93 | if (key && key->type == KE_KEY) { | 95 | key->keycode = keycode; |
94 | old_keycode = key->keycode; | 96 | set_bit(keycode, dev->keybit); |
95 | key->keycode = keycode; | 97 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) |
96 | set_bit(keycode, dev->keybit); | 98 | clear_bit(old_keycode, dev->keybit); |
97 | if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) | 99 | return 0; |
98 | clear_bit(old_keycode, dev->keybit); | 100 | } |
99 | return 0; | ||
100 | } | 101 | } |
101 | 102 | ||
102 | return -EINVAL; | 103 | return -EINVAL; |
@@ -164,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev, | |||
164 | return 0; | 165 | return 0; |
165 | 166 | ||
166 | err_out: | 167 | err_out: |
167 | kfree(keymap); | 168 | kfree(map); |
168 | return error; | 169 | return error; |
169 | 170 | ||
170 | } | 171 | } |
@@ -176,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup); | |||
176 | * | 177 | * |
177 | * This function is used to free memory allocated by sparse keymap | 178 | * This function is used to free memory allocated by sparse keymap |
178 | * in an input device that was set up by sparse_keymap_setup(). | 179 | * in an input device that was set up by sparse_keymap_setup(). |
180 | * NOTE: It is safe to cal this function while input device is | ||
181 | * still registered (however the drivers should care not to try to | ||
182 | * use freed keymap and thus have to shut off interrups/polling | ||
183 | * before freeing the keymap). | ||
179 | */ | 184 | */ |
180 | void sparse_keymap_free(struct input_dev *dev) | 185 | void sparse_keymap_free(struct input_dev *dev) |
181 | { | 186 | { |
187 | unsigned long flags; | ||
188 | |||
189 | /* | ||
190 | * Take event lock to prevent racing with input_get_keycode() | ||
191 | * and input_set_keycode() if we are called while input device | ||
192 | * is still registered. | ||
193 | */ | ||
194 | spin_lock_irqsave(&dev->event_lock, flags); | ||
195 | |||
182 | kfree(dev->keycode); | 196 | kfree(dev->keycode); |
183 | dev->keycode = NULL; | 197 | dev->keycode = NULL; |
184 | dev->keycodemax = 0; | 198 | dev->keycodemax = 0; |
185 | dev->getkeycode = NULL; | 199 | |
186 | dev->setkeycode = NULL; | 200 | spin_unlock_irqrestore(&dev->event_lock, flags); |
187 | } | 201 | } |
188 | EXPORT_SYMBOL(sparse_keymap_free); | 202 | EXPORT_SYMBOL(sparse_keymap_free); |
189 | 203 | ||
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 8b5d2873f0c4..f46502589e4e 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf) | |||
673 | int rv; | 673 | int rv; |
674 | 674 | ||
675 | mutex_lock(&wacom->lock); | 675 | mutex_lock(&wacom->lock); |
676 | if (wacom->open) { | 676 | |
677 | /* switch to wacom mode first */ | ||
678 | wacom_query_tablet_data(intf, features); | ||
679 | |||
680 | if (wacom->open) | ||
677 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 681 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
678 | /* switch to wacom mode if needed */ | 682 | else |
679 | if (!wacom_retrieve_hid_descriptor(intf, features)) | ||
680 | wacom_query_tablet_data(intf, features); | ||
681 | } else | ||
682 | rv = 0; | 683 | rv = 0; |
684 | |||
683 | mutex_unlock(&wacom->lock); | 685 | mutex_unlock(&wacom->lock); |
684 | 686 | ||
685 | return rv; | 687 | return rv; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3ba3437a2eb..4a852d815c68 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
155 | { | 155 | { |
156 | struct wacom_features *features = &wacom->features; | 156 | struct wacom_features *features = &wacom->features; |
157 | unsigned char *data = wacom->data; | 157 | unsigned char *data = wacom->data; |
158 | int x, y, prox; | 158 | int x, y, rw; |
159 | int rw = 0; | 159 | static int penData = 0; |
160 | int retval = 0; | ||
161 | 160 | ||
162 | if (data[0] != WACOM_REPORT_PENABLED) { | 161 | if (data[0] != WACOM_REPORT_PENABLED) { |
163 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 162 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
164 | goto exit; | 163 | return 0; |
165 | } | 164 | } |
166 | 165 | ||
167 | prox = data[1] & 0x80; | 166 | if (data[1] & 0x80) { |
168 | if (prox || wacom->id[0]) { | 167 | /* in prox and not a pad data */ |
169 | if (prox) { | 168 | penData = 1; |
170 | switch ((data[1] >> 5) & 3) { | 169 | |
170 | switch ((data[1] >> 5) & 3) { | ||
171 | 171 | ||
172 | case 0: /* Pen */ | 172 | case 0: /* Pen */ |
173 | wacom->tool[0] = BTN_TOOL_PEN; | 173 | wacom->tool[0] = BTN_TOOL_PEN; |
@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
181 | 181 | ||
182 | case 2: /* Mouse with wheel */ | 182 | case 2: /* Mouse with wheel */ |
183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); | 183 | wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); |
184 | if (features->type == WACOM_G4 || features->type == WACOM_MO) { | ||
185 | rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); | ||
186 | wacom_report_rel(wcombo, REL_WHEEL, -rw); | ||
187 | } else | ||
188 | wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); | ||
184 | /* fall through */ | 189 | /* fall through */ |
185 | 190 | ||
186 | case 3: /* Mouse without wheel */ | 191 | case 3: /* Mouse without wheel */ |
187 | wacom->tool[0] = BTN_TOOL_MOUSE; | 192 | wacom->tool[0] = BTN_TOOL_MOUSE; |
188 | wacom->id[0] = CURSOR_DEVICE_ID; | 193 | wacom->id[0] = CURSOR_DEVICE_ID; |
194 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
195 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
196 | if (features->type == WACOM_G4 || features->type == WACOM_MO) | ||
197 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
198 | else | ||
199 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
189 | break; | 200 | break; |
190 | } | ||
191 | } | 201 | } |
192 | x = wacom_le16_to_cpu(&data[2]); | 202 | x = wacom_le16_to_cpu(&data[2]); |
193 | y = wacom_le16_to_cpu(&data[4]); | 203 | y = wacom_le16_to_cpu(&data[4]); |
@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
198 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); | 208 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); |
199 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
200 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
201 | } else { | ||
202 | wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); | ||
203 | wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); | ||
204 | if (features->type == WACOM_G4 || | ||
205 | features->type == WACOM_MO) { | ||
206 | wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); | ||
207 | rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); | ||
208 | } else { | ||
209 | wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); | ||
210 | rw = -(signed)data[6]; | ||
211 | } | ||
212 | wacom_report_rel(wcombo, REL_WHEEL, rw); | ||
213 | } | 211 | } |
214 | |||
215 | if (!prox) | ||
216 | wacom->id[0] = 0; | ||
217 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ | 212 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ |
218 | wacom_report_key(wcombo, wacom->tool[0], prox); | 213 | wacom_report_key(wcombo, wacom->tool[0], 1); |
219 | wacom_input_sync(wcombo); /* sync last event */ | 214 | } else if (wacom->id[0]) { |
215 | wacom_report_abs(wcombo, ABS_X, 0); | ||
216 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
217 | if (wacom->tool[0] == BTN_TOOL_MOUSE) { | ||
218 | wacom_report_key(wcombo, BTN_LEFT, 0); | ||
219 | wacom_report_key(wcombo, BTN_RIGHT, 0); | ||
220 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | ||
221 | } else { | ||
222 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
223 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
224 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
225 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
226 | } | ||
227 | wacom->id[0] = 0; | ||
228 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | ||
229 | wacom_report_key(wcombo, wacom->tool[0], 0); | ||
220 | } | 230 | } |
221 | 231 | ||
222 | /* send pad data */ | 232 | /* send pad data */ |
223 | switch (features->type) { | 233 | switch (features->type) { |
224 | case WACOM_G4: | 234 | case WACOM_G4: |
225 | prox = data[7] & 0xf8; | 235 | if (data[7] & 0xf8) { |
226 | if (prox || wacom->id[1]) { | 236 | if (penData) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
227 | wacom->id[1] = PAD_DEVICE_ID; | 241 | wacom->id[1] = PAD_DEVICE_ID; |
228 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
229 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
231 | wacom_report_rel(wcombo, REL_WHEEL, rw); | 245 | wacom_report_rel(wcombo, REL_WHEEL, rw); |
232 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 246 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
233 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
234 | if (!prox) | 248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
235 | wacom->id[1] = 0; | 249 | } else if (wacom->id[1]) { |
236 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 250 | if (penData) { |
251 | wacom_input_sync(wcombo); /* sync last event */ | ||
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
255 | wacom->id[1] = 0; | ||
256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | ||
257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | ||
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
260 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
237 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
238 | } | 262 | } |
239 | retval = 1; | ||
240 | break; | 263 | break; |
241 | case WACOM_MO: | 264 | case WACOM_MO: |
242 | prox = (data[7] & 0xf8) || data[8]; | 265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
243 | if (prox || wacom->id[1]) { | 266 | if (penData) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | ||
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
244 | wacom->id[1] = PAD_DEVICE_ID; | 271 | wacom->id[1] = PAD_DEVICE_ID; |
245 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
246 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
248 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | 275 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); |
249 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | 276 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); |
250 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); | 277 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); |
251 | if (!prox) | ||
252 | wacom->id[1] = 0; | ||
253 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
254 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
280 | } else if (wacom->id[1]) { | ||
281 | if (penData) { | ||
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
286 | wacom->id[1] = 0; | ||
287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | ||
288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | ||
289 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); | ||
290 | wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); | ||
291 | wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); | ||
292 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | ||
293 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
294 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
255 | } | 295 | } |
256 | retval = 1; | ||
257 | break; | 296 | break; |
258 | } | 297 | } |
259 | exit: | 298 | return 1; |
260 | return retval; | ||
261 | } | 299 | } |
262 | 300 | ||
263 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 301 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) |
@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
598 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | 636 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) |
599 | { | 637 | { |
600 | wacom_report_abs(wcombo, ABS_X, | 638 | wacom_report_abs(wcombo, ABS_X, |
601 | data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); | 639 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); |
602 | wacom_report_abs(wcombo, ABS_Y, | 640 | wacom_report_abs(wcombo, ABS_Y, |
603 | data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); | 641 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); |
604 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
605 | wacom_report_key(wcombo, wacom->tool[idx], 1); | 643 | wacom_report_key(wcombo, wacom->tool[idx], 1); |
606 | if (idx) | 644 | if (idx) |
@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
744 | 782 | ||
745 | touchInProx = 0; | 783 | touchInProx = 0; |
746 | 784 | ||
747 | if (!wacom->id[0]) { /* first in prox */ | 785 | if (prox) { /* in prox */ |
748 | /* Going into proximity select tool */ | 786 | if (!wacom->id[0]) { |
749 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 787 | /* Going into proximity select tool */ |
750 | if (wacom->tool[0] == BTN_TOOL_PEN) | 788 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
751 | wacom->id[0] = STYLUS_DEVICE_ID; | 789 | if (wacom->tool[0] == BTN_TOOL_PEN) |
752 | else | 790 | wacom->id[0] = STYLUS_DEVICE_ID; |
753 | wacom->id[0] = ERASER_DEVICE_ID; | 791 | else |
754 | } | 792 | wacom->id[0] = ERASER_DEVICE_ID; |
755 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 793 | } |
756 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 794 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
757 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | 795 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
758 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | 796 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); |
759 | pressure = ((data[7] & 0x01) << 8) | data[6]; | 797 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); |
760 | if (pressure < 0) | 798 | pressure = ((data[7] & 0x01) << 8) | data[6]; |
761 | pressure = features->pressure_max + pressure + 1; | 799 | if (pressure < 0) |
762 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 800 | pressure = features->pressure_max + pressure + 1; |
763 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); | 801 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
764 | if (!prox) { /* out-prox */ | 802 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
803 | } else { | ||
804 | wacom_report_abs(wcombo, ABS_X, 0); | ||
805 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
806 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | ||
807 | wacom_report_key(wcombo, BTN_STYLUS, 0); | ||
808 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | ||
809 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
765 | wacom->id[0] = 0; | 810 | wacom->id[0] = 0; |
766 | /* pen is out so touch can be enabled now */ | 811 | /* pen is out so touch can be enabled now */ |
767 | touchInProx = 1; | 812 | touchInProx = 1; |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 0be15c70c16d..47a5ffec55a3 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -14,11 +14,6 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | |||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/timer.h> | ||
22 | #include <linux/usb.h> | 17 | #include <linux/usb.h> |
23 | #include <linux/module.h> | 18 | #include <linux/module.h> |
24 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index eb7e27105a82..964a55fb1486 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c | |||
@@ -12,8 +12,6 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "gigaset.h" | 14 | #include "gigaset.h" |
15 | #include <linux/slab.h> | ||
16 | #include <linux/ctype.h> | ||
17 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
18 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
19 | #include <linux/isdn/capilli.h> | 17 | #include <linux/isdn/capilli.h> |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 0b39b387c125..f6f45f221920 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -14,10 +14,8 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/ctype.h> | ||
18 | #include <linux/module.h> | 17 | #include <linux/module.h> |
19 | #include <linux/moduleparam.h> | 18 | #include <linux/moduleparam.h> |
20 | #include <linux/slab.h> | ||
21 | 19 | ||
22 | /* Version Information */ | 20 | /* Version Information */ |
23 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers" | 21 | #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers" |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 9ef5b0463fd5..05947f9c1849 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -20,11 +20,12 @@ | |||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/sched.h> | ||
23 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/ctype.h> | ||
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
26 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
27 | #include <linux/usb.h> | ||
28 | #include <linux/skbuff.h> | 29 | #include <linux/skbuff.h> |
29 | #include <linux/netdevice.h> | 30 | #include <linux/netdevice.h> |
30 | #include <linux/ppp_defs.h> | 31 | #include <linux/ppp_defs.h> |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index c99fb9790a13..c22e5ace8276 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/isdnif.h> | 17 | #include <linux/isdnif.h> |
18 | #include <linux/slab.h> | ||
19 | 18 | ||
20 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ | 19 | #define HW_HDR_LEN 2 /* Header size used to store ack info */ |
21 | 20 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index f0dc6c9cc283..c9f28dd40d5c 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include "gigaset.h" | 14 | #include "gigaset.h" |
15 | #include <linux/gigaset_dev.h> | 15 | #include <linux/gigaset_dev.h> |
16 | #include <linux/tty.h> | ||
17 | #include <linux/tty_flip.h> | 16 | #include <linux/tty_flip.h> |
18 | 17 | ||
19 | /*** our ioctls ***/ | 18 | /*** our ioctls ***/ |
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index b69f73a0668f..b943efbff44d 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -14,7 +14,6 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/ctype.h> | ||
18 | 17 | ||
19 | static ssize_t show_cidmode(struct device *dev, | 18 | static ssize_t show_cidmode(struct device *dev, |
20 | struct device_attribute *attr, char *buf) | 19 | struct device_attribute *attr, char *buf) |
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 8b0afd203a07..e96c0586886c 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -11,13 +11,10 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "gigaset.h" | 13 | #include "gigaset.h" |
14 | |||
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
16 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
18 | #include <linux/tty.h> | ||
19 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
20 | #include <linux/slab.h> | ||
21 | 18 | ||
22 | /* Version Information */ | 19 | /* Version Information */ |
23 | #define DRIVER_AUTHOR "Tilman Schmidt" | 20 | #define DRIVER_AUTHOR "Tilman Schmidt" |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 9430a2bbb523..76dbb20f3065 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -16,10 +16,6 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "gigaset.h" | 18 | #include "gigaset.h" |
19 | |||
20 | #include <linux/errno.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
24 | #include <linux/module.h> | 20 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 21 | #include <linux/moduleparam.h> |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 07090f379c63..69c84a1d88ea 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -178,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status) | |||
178 | 178 | ||
179 | /* We set the status. */ | 179 | /* We set the status. */ |
180 | to_lgdev(vdev)->desc->status = status; | 180 | to_lgdev(vdev)->desc->status = status; |
181 | kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset); | 181 | hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0); |
182 | } | 182 | } |
183 | 183 | ||
184 | static void lg_set_status(struct virtio_device *vdev, u8 status) | 184 | static void lg_set_status(struct virtio_device *vdev, u8 status) |
@@ -229,7 +229,7 @@ static void lg_notify(struct virtqueue *vq) | |||
229 | */ | 229 | */ |
230 | struct lguest_vq_info *lvq = vq->priv; | 230 | struct lguest_vq_info *lvq = vq->priv; |
231 | 231 | ||
232 | kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT); | 232 | hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0); |
233 | } | 233 | } |
234 | 234 | ||
235 | /* An extern declaration inside a C file is bad form. Don't do it. */ | 235 | /* An extern declaration inside a C file is bad form. Don't do it. */ |
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index fb2b7ef7868e..b4eb675a807e 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -288,6 +288,18 @@ static int emulate_insn(struct lg_cpu *cpu) | |||
288 | insn = lgread(cpu, physaddr, u8); | 288 | insn = lgread(cpu, physaddr, u8); |
289 | 289 | ||
290 | /* | 290 | /* |
291 | * Around 2.6.33, the kernel started using an emulation for the | ||
292 | * cmpxchg8b instruction in early boot on many configurations. This | ||
293 | * code isn't paravirtualized, and it tries to disable interrupts. | ||
294 | * Ignore it, which will Mostly Work. | ||
295 | */ | ||
296 | if (insn == 0xfa) { | ||
297 | /* "cli", or Clear Interrupt Enable instruction. Skip it. */ | ||
298 | cpu->regs->eip++; | ||
299 | return 1; | ||
300 | } | ||
301 | |||
302 | /* | ||
291 | * 0x66 is an "operand prefix". It means it's using the upper 16 bits | 303 | * 0x66 is an "operand prefix". It means it's using the upper 16 bits |
292 | * of the eax register. | 304 | * of the eax register. |
293 | */ | 305 | */ |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e3e9a36ea3b7..20e48401910e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1650,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1650 | int previous, int *dd_idx, | 1650 | int previous, int *dd_idx, |
1651 | struct stripe_head *sh) | 1651 | struct stripe_head *sh) |
1652 | { | 1652 | { |
1653 | long stripe; | 1653 | sector_t stripe; |
1654 | unsigned long chunk_number; | 1654 | sector_t chunk_number; |
1655 | unsigned int chunk_offset; | 1655 | unsigned int chunk_offset; |
1656 | int pd_idx, qd_idx; | 1656 | int pd_idx, qd_idx; |
1657 | int ddf_layout = 0; | 1657 | int ddf_layout = 0; |
@@ -1671,17 +1671,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, | |||
1671 | */ | 1671 | */ |
1672 | chunk_offset = sector_div(r_sector, sectors_per_chunk); | 1672 | chunk_offset = sector_div(r_sector, sectors_per_chunk); |
1673 | chunk_number = r_sector; | 1673 | chunk_number = r_sector; |
1674 | BUG_ON(r_sector != chunk_number); | ||
1675 | 1674 | ||
1676 | /* | 1675 | /* |
1677 | * Compute the stripe number | 1676 | * Compute the stripe number |
1678 | */ | 1677 | */ |
1679 | stripe = chunk_number / data_disks; | 1678 | stripe = chunk_number; |
1680 | 1679 | *dd_idx = sector_div(stripe, data_disks); | |
1681 | /* | ||
1682 | * Compute the data disk and parity disk indexes inside the stripe | ||
1683 | */ | ||
1684 | *dd_idx = chunk_number % data_disks; | ||
1685 | 1680 | ||
1686 | /* | 1681 | /* |
1687 | * Select the parity disk based on the user selected algorithm. | 1682 | * Select the parity disk based on the user selected algorithm. |
@@ -1870,14 +1865,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1870 | : conf->algorithm; | 1865 | : conf->algorithm; |
1871 | sector_t stripe; | 1866 | sector_t stripe; |
1872 | int chunk_offset; | 1867 | int chunk_offset; |
1873 | int chunk_number, dummy1, dd_idx = i; | 1868 | sector_t chunk_number; |
1869 | int dummy1, dd_idx = i; | ||
1874 | sector_t r_sector; | 1870 | sector_t r_sector; |
1875 | struct stripe_head sh2; | 1871 | struct stripe_head sh2; |
1876 | 1872 | ||
1877 | 1873 | ||
1878 | chunk_offset = sector_div(new_sector, sectors_per_chunk); | 1874 | chunk_offset = sector_div(new_sector, sectors_per_chunk); |
1879 | stripe = new_sector; | 1875 | stripe = new_sector; |
1880 | BUG_ON(new_sector != stripe); | ||
1881 | 1876 | ||
1882 | if (i == sh->pd_idx) | 1877 | if (i == sh->pd_idx) |
1883 | return 0; | 1878 | return 0; |
@@ -1970,7 +1965,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) | |||
1970 | } | 1965 | } |
1971 | 1966 | ||
1972 | chunk_number = stripe * data_disks + i; | 1967 | chunk_number = stripe * data_disks + i; |
1973 | r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset; | 1968 | r_sector = chunk_number * sectors_per_chunk + chunk_offset; |
1974 | 1969 | ||
1975 | check = raid5_compute_sector(conf, r_sector, | 1970 | check = raid5_compute_sector(conf, r_sector, |
1976 | previous, &dummy1, &sh2); | 1971 | previous, &dummy1, &sh2); |
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 9781942992e9..4b451a7c03e9 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk) | |||
2334 | struct cnic_local *cp = dev->cnic_priv; | 2334 | struct cnic_local *cp = dev->cnic_priv; |
2335 | u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX; | 2335 | u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX; |
2336 | 2336 | ||
2337 | prefetch(cp->status_blk.bnx2x); | 2337 | if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) { |
2338 | prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]); | 2338 | prefetch(cp->status_blk.bnx2x); |
2339 | prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]); | ||
2339 | 2340 | ||
2340 | if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) | ||
2341 | tasklet_schedule(&cp->cnic_irq_task); | 2341 | tasklet_schedule(&cp->cnic_irq_task); |
2342 | 2342 | cnic_chk_pkt_rings(cp); | |
2343 | cnic_chk_pkt_rings(cp); | 2343 | } |
2344 | 2344 | ||
2345 | return 0; | 2345 | return 0; |
2346 | } | 2346 | } |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index cfd09cea7214..73d43c53015a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -661,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
661 | i = 0; | 661 | i = 0; |
662 | } | 662 | } |
663 | 663 | ||
664 | if (i == tx_ring->next_to_use) | ||
665 | break; | ||
664 | eop = tx_ring->buffer_info[i].next_to_watch; | 666 | eop = tx_ring->buffer_info[i].next_to_watch; |
665 | eop_desc = E1000_TX_DESC(*tx_ring, eop); | 667 | eop_desc = E1000_TX_DESC(*tx_ring, eop); |
666 | } | 668 | } |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 73b260c3c654..5c98f7c22425 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -5899,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5899 | /* Limit the number of tx's outstanding for hw bug */ | 5899 | /* Limit the number of tx's outstanding for hw bug */ |
5900 | if (id->driver_data & DEV_NEED_TX_LIMIT) { | 5900 | if (id->driver_data & DEV_NEED_TX_LIMIT) { |
5901 | np->tx_limit = 1; | 5901 | np->tx_limit = 1; |
5902 | if ((id->driver_data & DEV_NEED_TX_LIMIT2) && | 5902 | if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) && |
5903 | pci_dev->revision >= 0xA2) | 5903 | pci_dev->revision >= 0xA2) |
5904 | np->tx_limit = 0; | 5904 | np->tx_limit = 0; |
5905 | } | 5905 | } |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index d313fae992da..743038490104 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -1814,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter, | |||
1814 | retval = 0; | 1814 | retval = 0; |
1815 | break; | 1815 | break; |
1816 | case E1000_DEV_ID_82576_QUAD_COPPER: | 1816 | case E1000_DEV_ID_82576_QUAD_COPPER: |
1817 | case E1000_DEV_ID_82576_QUAD_COPPER_ET2: | ||
1817 | /* quad port adapters only support WoL on port A */ | 1818 | /* quad port adapters only support WoL on port A */ |
1818 | if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) { | 1819 | if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) { |
1819 | wol->supported = 0; | 1820 | wol->supported = 0; |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9b3c51ab1758..c9baa2aa98cd 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1612,6 +1612,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1612 | adapter->eeprom_wol = 0; | 1612 | adapter->eeprom_wol = 0; |
1613 | break; | 1613 | break; |
1614 | case E1000_DEV_ID_82576_QUAD_COPPER: | 1614 | case E1000_DEV_ID_82576_QUAD_COPPER: |
1615 | case E1000_DEV_ID_82576_QUAD_COPPER_ET2: | ||
1615 | /* if quad port adapter, disable WoL on all but port A */ | 1616 | /* if quad port adapter, disable WoL on all but port A */ |
1616 | if (global_quad_port_a != 0) | 1617 | if (global_quad_port_a != 0) |
1617 | adapter->eeprom_wol = 0; | 1618 | adapter->eeprom_wol = 0; |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 471887742b02..ecde0876a785 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -1690,7 +1690,7 @@ myri10ge_set_pauseparam(struct net_device *netdev, | |||
1690 | if (pause->tx_pause != mgp->pause) | 1690 | if (pause->tx_pause != mgp->pause) |
1691 | return myri10ge_change_pause(mgp, pause->tx_pause); | 1691 | return myri10ge_change_pause(mgp, pause->tx_pause); |
1692 | if (pause->rx_pause != mgp->pause) | 1692 | if (pause->rx_pause != mgp->pause) |
1693 | return myri10ge_change_pause(mgp, pause->tx_pause); | 1693 | return myri10ge_change_pause(mgp, pause->rx_pause); |
1694 | if (pause->autoneg != 0) | 1694 | if (pause->autoneg != 0) |
1695 | return -EINVAL; | 1695 | return -EINVAL; |
1696 | return 0; | 1696 | return 0; |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index ff7eb9116b6a..fd9d6e34fda4 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -1608,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev) | |||
1608 | { | 1608 | { |
1609 | unsigned int ioaddr = dev->base_addr; | 1609 | unsigned int ioaddr = dev->base_addr; |
1610 | struct smc_private *smc = netdev_priv(dev); | 1610 | struct smc_private *smc = netdev_priv(dev); |
1611 | u_int multicast_table[ 2 ] = { 0, }; | 1611 | unsigned char multicast_table[8]; |
1612 | unsigned long flags; | 1612 | unsigned long flags; |
1613 | u_short rx_cfg_setting; | 1613 | u_short rx_cfg_setting; |
1614 | int i; | ||
1615 | |||
1616 | memset(multicast_table, 0, sizeof(multicast_table)); | ||
1614 | 1617 | ||
1615 | if (dev->flags & IFF_PROMISC) { | 1618 | if (dev->flags & IFF_PROMISC) { |
1616 | rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti; | 1619 | rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti; |
@@ -1622,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev) | |||
1622 | 1625 | ||
1623 | netdev_for_each_mc_addr(mc_addr, dev) { | 1626 | netdev_for_each_mc_addr(mc_addr, dev) { |
1624 | u_int position = ether_crc(6, mc_addr->dmi_addr); | 1627 | u_int position = ether_crc(6, mc_addr->dmi_addr); |
1625 | #ifndef final_version /* Verify multicast address. */ | ||
1626 | if ((mc_addr->dmi_addr[0] & 1) == 0) | ||
1627 | continue; | ||
1628 | #endif | ||
1629 | multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); | 1628 | multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); |
1630 | } | 1629 | } |
1631 | } | 1630 | } |
@@ -1635,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev) | |||
1635 | /* Load MC table and Rx setting into the chip without interrupts. */ | 1634 | /* Load MC table and Rx setting into the chip without interrupts. */ |
1636 | spin_lock_irqsave(&smc->lock, flags); | 1635 | spin_lock_irqsave(&smc->lock, flags); |
1637 | SMC_SELECT_BANK(3); | 1636 | SMC_SELECT_BANK(3); |
1638 | outl(multicast_table[0], ioaddr + MULTICAST0); | 1637 | for (i = 0; i < 8; i++) |
1639 | outl(multicast_table[1], ioaddr + MULTICAST4); | 1638 | outb(multicast_table[i], ioaddr + MULTICAST0 + i); |
1640 | SMC_SELECT_BANK(0); | 1639 | SMC_SELECT_BANK(0); |
1641 | outw(rx_cfg_setting, ioaddr + RCR); | 1640 | outw(rx_cfg_setting, ioaddr + RCR); |
1642 | SMC_SELECT_BANK(2); | 1641 | SMC_SELECT_BANK(2); |
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index a6ef266a2fe2..e73ba455aa20 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -431,6 +431,9 @@ void qlcnic_set_multi(struct net_device *netdev) | |||
431 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 431 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
432 | u32 mode = VPORT_MISS_MODE_DROP; | 432 | u32 mode = VPORT_MISS_MODE_DROP; |
433 | 433 | ||
434 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
435 | return; | ||
436 | |||
434 | qlcnic_nic_add_mac(adapter, adapter->mac_addr); | 437 | qlcnic_nic_add_mac(adapter, adapter->mac_addr); |
435 | qlcnic_nic_add_mac(adapter, bcast_addr); | 438 | qlcnic_nic_add_mac(adapter, bcast_addr); |
436 | 439 | ||
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 43afdb6b25e6..0298d8c1dcb6 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -134,7 +134,7 @@ | |||
134 | #define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) | 134 | #define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) |
135 | #define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) | 135 | #define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) |
136 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ | 136 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ |
137 | #define MCAST_MAX 4 /* Max number multicast addresses to filter */ | 137 | #define MCAST_MAX 3 /* Max number multicast addresses to filter */ |
138 | 138 | ||
139 | /* Descriptor status */ | 139 | /* Descriptor status */ |
140 | #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ | 140 | #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ |
@@ -982,9 +982,6 @@ static void r6040_multicast_list(struct net_device *dev) | |||
982 | crc >>= 26; | 982 | crc >>= 26; |
983 | hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); | 983 | hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); |
984 | } | 984 | } |
985 | /* Write the index of the hash table */ | ||
986 | for (i = 0; i < 4; i++) | ||
987 | iowrite16(hash_table[i] << 14, ioaddr + MCR1); | ||
988 | /* Fill the MAC hash tables with their values */ | 985 | /* Fill the MAC hash tables with their values */ |
989 | iowrite16(hash_table[0], ioaddr + MAR0); | 986 | iowrite16(hash_table[0], ioaddr + MAR0); |
990 | iowrite16(hash_table[1], ioaddr + MAR1); | 987 | iowrite16(hash_table[1], ioaddr + MAR1); |
@@ -1000,9 +997,9 @@ static void r6040_multicast_list(struct net_device *dev) | |||
1000 | iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); | 997 | iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); |
1001 | iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); | 998 | iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); |
1002 | } else { | 999 | } else { |
1003 | iowrite16(0xffff, ioaddr + MID_0L + 8 * i); | 1000 | iowrite16(0xffff, ioaddr + MID_1L + 8 * i); |
1004 | iowrite16(0xffff, ioaddr + MID_0M + 8 * i); | 1001 | iowrite16(0xffff, ioaddr + MID_1M + 8 * i); |
1005 | iowrite16(0xffff, ioaddr + MID_0H + 8 * i); | 1002 | iowrite16(0xffff, ioaddr + MID_1H + 8 * i); |
1006 | } | 1003 | } |
1007 | i++; | 1004 | i++; |
1008 | } | 1005 | } |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index a214a1627e8b..4111a85ec80e 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -1686,7 +1686,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1686 | } | 1686 | } |
1687 | pr_info("done!\n"); | 1687 | pr_info("done!\n"); |
1688 | 1688 | ||
1689 | if (!request_mem_region(res->start, (res->end - res->start), | 1689 | if (!request_mem_region(res->start, resource_size(res), |
1690 | pdev->name)) { | 1690 | pdev->name)) { |
1691 | pr_err("%s: ERROR: memory allocation failed" | 1691 | pr_err("%s: ERROR: memory allocation failed" |
1692 | "cannot get the I/O addr 0x%x\n", | 1692 | "cannot get the I/O addr 0x%x\n", |
@@ -1695,9 +1695,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1695 | goto out; | 1695 | goto out; |
1696 | } | 1696 | } |
1697 | 1697 | ||
1698 | addr = ioremap(res->start, (res->end - res->start)); | 1698 | addr = ioremap(res->start, resource_size(res)); |
1699 | if (!addr) { | 1699 | if (!addr) { |
1700 | pr_err("%s: ERROR: memory mapping failed \n", __func__); | 1700 | pr_err("%s: ERROR: memory mapping failed\n", __func__); |
1701 | ret = -ENOMEM; | 1701 | ret = -ENOMEM; |
1702 | goto out; | 1702 | goto out; |
1703 | } | 1703 | } |
@@ -1775,7 +1775,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) | |||
1775 | out: | 1775 | out: |
1776 | if (ret < 0) { | 1776 | if (ret < 0) { |
1777 | platform_set_drvdata(pdev, NULL); | 1777 | platform_set_drvdata(pdev, NULL); |
1778 | release_mem_region(res->start, (res->end - res->start)); | 1778 | release_mem_region(res->start, resource_size(res)); |
1779 | if (addr != NULL) | 1779 | if (addr != NULL) |
1780 | iounmap(addr); | 1780 | iounmap(addr); |
1781 | } | 1781 | } |
@@ -1813,7 +1813,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev) | |||
1813 | 1813 | ||
1814 | iounmap((void *)ndev->base_addr); | 1814 | iounmap((void *)ndev->base_addr); |
1815 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1815 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1816 | release_mem_region(res->start, (res->end - res->start)); | 1816 | release_mem_region(res->start, resource_size(res)); |
1817 | 1817 | ||
1818 | free_netdev(ndev); | 1818 | free_netdev(ndev); |
1819 | 1819 | ||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 96c39bddc78c..43265207d463 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -387,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
387 | } | 387 | } |
388 | } | 388 | } |
389 | 389 | ||
390 | /* Orphan the skb - required as we might hang on to it | ||
391 | * for indefinite time. */ | ||
392 | skb_orphan(skb); | ||
393 | |||
390 | /* Enqueue packet */ | 394 | /* Enqueue packet */ |
391 | skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); | 395 | skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); |
392 | dev->trans_start = jiffies; | 396 | dev->trans_start = jiffies; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 6fb783ce20b9..b0577dd1a42d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -327,6 +327,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp) | |||
327 | struct scatterlist sg[2]; | 327 | struct scatterlist sg[2]; |
328 | int err; | 328 | int err; |
329 | 329 | ||
330 | sg_init_table(sg, 2); | ||
330 | skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN); | 331 | skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN); |
331 | if (unlikely(!skb)) | 332 | if (unlikely(!skb)) |
332 | return -ENOMEM; | 333 | return -ENOMEM; |
@@ -352,6 +353,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp) | |||
352 | char *p; | 353 | char *p; |
353 | int i, err, offset; | 354 | int i, err, offset; |
354 | 355 | ||
356 | sg_init_table(sg, MAX_SKB_FRAGS + 2); | ||
355 | /* page in sg[MAX_SKB_FRAGS + 1] is list tail */ | 357 | /* page in sg[MAX_SKB_FRAGS + 1] is list tail */ |
356 | for (i = MAX_SKB_FRAGS + 1; i > 1; --i) { | 358 | for (i = MAX_SKB_FRAGS + 1; i > 1; --i) { |
357 | first = get_a_page(vi, gfp); | 359 | first = get_a_page(vi, gfp); |
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index b9b9d6b01c0b..941f053e650e 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c | |||
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *dev) | |||
628 | ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL); | 628 | ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL); |
629 | } | 629 | } |
630 | 630 | ||
631 | static void ppp_close(struct net_device *dev) | ||
632 | { | ||
633 | ppp_tx_flush(); | ||
634 | } | ||
635 | |||
631 | static struct hdlc_proto proto = { | 636 | static struct hdlc_proto proto = { |
632 | .start = ppp_start, | 637 | .start = ppp_start, |
633 | .stop = ppp_stop, | 638 | .stop = ppp_stop, |
639 | .close = ppp_close, | ||
634 | .type_trans = ppp_type_trans, | 640 | .type_trans = ppp_type_trans, |
635 | .ioctl = ppp_ioctl, | 641 | .ioctl = ppp_ioctl, |
636 | .netif_rx = ppp_rx, | 642 | .netif_rx = ppp_rx, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 67ca4e5a6017..115e1aeedb59 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1532 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); | 1532 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); |
1533 | ath9k_set_wiphy_idle(aphy, idle); | 1533 | ath9k_set_wiphy_idle(aphy, idle); |
1534 | 1534 | ||
1535 | if (!idle && all_wiphys_idle) | 1535 | enable_radio = (!idle && all_wiphys_idle); |
1536 | enable_radio = true; | ||
1537 | 1536 | ||
1538 | /* | 1537 | /* |
1539 | * After we unlock here its possible another wiphy | 1538 | * After we unlock here its possible another wiphy |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 83c52a682622..8972166386cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2015 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " | 2015 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " |
2016 | "%d index %d\n", scd_ssn , index); | 2016 | "%d index %d\n", scd_ssn , index); |
2017 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2017 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2018 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | 2018 | if (qc) |
2019 | iwl_free_tfds_in_queue(priv, sta_id, | ||
2020 | tid, freed); | ||
2019 | 2021 | ||
2020 | if (priv->mac80211_registered && | 2022 | if (priv->mac80211_registered && |
2021 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && | 2023 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
@@ -2041,14 +2043,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2041 | tx_resp->failure_frame); | 2043 | tx_resp->failure_frame); |
2042 | 2044 | ||
2043 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2045 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2044 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | 2046 | if (qc && likely(sta_id != IWL_INVALID_STATION)) |
2047 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); | ||
2048 | else if (sta_id == IWL_INVALID_STATION) | ||
2049 | IWL_DEBUG_TX_REPLY(priv, "Station not known\n"); | ||
2045 | 2050 | ||
2046 | if (priv->mac80211_registered && | 2051 | if (priv->mac80211_registered && |
2047 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 2052 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
2048 | iwl_wake_queue(priv, txq_id); | 2053 | iwl_wake_queue(priv, txq_id); |
2049 | } | 2054 | } |
2050 | 2055 | if (qc && likely(sta_id != IWL_INVALID_STATION)) | |
2051 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 2056 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
2052 | 2057 | ||
2053 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 2058 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
2054 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | 2059 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 35f819ac87a3..1460116d329f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -346,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | |||
346 | !!(rate_n_flags & RATE_MCS_ANT_C_MSK); | 346 | !!(rate_n_flags & RATE_MCS_ANT_C_MSK); |
347 | } | 347 | } |
348 | 348 | ||
349 | /* | ||
350 | * Static function to get the expected throughput from an iwl_scale_tbl_info | ||
351 | * that wraps a NULL pointer check | ||
352 | */ | ||
353 | static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) | ||
354 | { | ||
355 | if (tbl->expected_tpt) | ||
356 | return tbl->expected_tpt[rs_index]; | ||
357 | return 0; | ||
358 | } | ||
359 | |||
349 | /** | 360 | /** |
350 | * rs_collect_tx_data - Update the success/failure sliding window | 361 | * rs_collect_tx_data - Update the success/failure sliding window |
351 | * | 362 | * |
@@ -353,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | |||
353 | * at this rate. window->data contains the bitmask of successful | 364 | * at this rate. window->data contains the bitmask of successful |
354 | * packets. | 365 | * packets. |
355 | */ | 366 | */ |
356 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | 367 | static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, |
357 | int scale_index, s32 tpt, int attempts, | 368 | int scale_index, int attempts, int successes) |
358 | int successes) | ||
359 | { | 369 | { |
360 | struct iwl_rate_scale_data *window = NULL; | 370 | struct iwl_rate_scale_data *window = NULL; |
361 | static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); | 371 | static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); |
362 | s32 fail_count; | 372 | s32 fail_count, tpt; |
363 | 373 | ||
364 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) | 374 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) |
365 | return -EINVAL; | 375 | return -EINVAL; |
366 | 376 | ||
367 | /* Select window for current tx bit rate */ | 377 | /* Select window for current tx bit rate */ |
368 | window = &(windows[scale_index]); | 378 | window = &(tbl->win[scale_index]); |
379 | |||
380 | /* Get expected throughput */ | ||
381 | tpt = get_expected_tpt(tbl, scale_index); | ||
369 | 382 | ||
370 | /* | 383 | /* |
371 | * Keep track of only the latest 62 tx frame attempts in this rate's | 384 | * Keep track of only the latest 62 tx frame attempts in this rate's |
@@ -739,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, | |||
739 | return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && | 752 | return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && |
740 | (a->is_SGI == b->is_SGI); | 753 | (a->is_SGI == b->is_SGI); |
741 | } | 754 | } |
742 | /* | ||
743 | * Static function to get the expected throughput from an iwl_scale_tbl_info | ||
744 | * that wraps a NULL pointer check | ||
745 | */ | ||
746 | static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) | ||
747 | { | ||
748 | if (tbl->expected_tpt) | ||
749 | return tbl->expected_tpt[rs_index]; | ||
750 | return 0; | ||
751 | } | ||
752 | 755 | ||
753 | /* | 756 | /* |
754 | * mac80211 sends us Tx status | 757 | * mac80211 sends us Tx status |
@@ -765,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
765 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 768 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
766 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 769 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; |
767 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 770 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
768 | struct iwl_rate_scale_data *window = NULL; | ||
769 | enum mac80211_rate_control_flags mac_flags; | 771 | enum mac80211_rate_control_flags mac_flags; |
770 | u32 tx_rate; | 772 | u32 tx_rate; |
771 | struct iwl_scale_tbl_info tbl_type; | 773 | struct iwl_scale_tbl_info tbl_type; |
772 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl; | 774 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; |
773 | s32 tpt = 0; | ||
774 | 775 | ||
775 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); | 776 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); |
776 | 777 | ||
@@ -853,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
853 | IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); | 854 | IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); |
854 | return; | 855 | return; |
855 | } | 856 | } |
856 | window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); | ||
857 | 857 | ||
858 | /* | 858 | /* |
859 | * Updating the frame history depends on whether packets were | 859 | * Updating the frame history depends on whether packets were |
@@ -866,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
866 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); | 866 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); |
867 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, | 867 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, |
868 | &rs_index); | 868 | &rs_index); |
869 | tpt = get_expected_tpt(curr_tbl, rs_index); | 869 | rs_collect_tx_data(curr_tbl, rs_index, |
870 | rs_collect_tx_data(window, rs_index, tpt, | ||
871 | info->status.ampdu_ack_len, | 870 | info->status.ampdu_ack_len, |
872 | info->status.ampdu_ack_map); | 871 | info->status.ampdu_ack_map); |
873 | 872 | ||
@@ -897,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
897 | * table as active/search. | 896 | * table as active/search. |
898 | */ | 897 | */ |
899 | if (table_type_matches(&tbl_type, curr_tbl)) | 898 | if (table_type_matches(&tbl_type, curr_tbl)) |
900 | tpt = get_expected_tpt(curr_tbl, rs_index); | 899 | tmp_tbl = curr_tbl; |
901 | else if (table_type_matches(&tbl_type, other_tbl)) | 900 | else if (table_type_matches(&tbl_type, other_tbl)) |
902 | tpt = get_expected_tpt(other_tbl, rs_index); | 901 | tmp_tbl = other_tbl; |
903 | else | 902 | else |
904 | continue; | 903 | continue; |
905 | 904 | rs_collect_tx_data(tmp_tbl, rs_index, 1, | |
906 | /* Constants mean 1 transmission, 0 successes */ | 905 | i < retries ? 0 : legacy_success); |
907 | if (i < retries) | ||
908 | rs_collect_tx_data(window, rs_index, tpt, 1, | ||
909 | 0); | ||
910 | else | ||
911 | rs_collect_tx_data(window, rs_index, tpt, 1, | ||
912 | legacy_success); | ||
913 | } | 906 | } |
914 | 907 | ||
915 | /* Update success/fail counts if not searching for new mode */ | 908 | /* Update success/fail counts if not searching for new mode */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index de3b3f403d1f..8b516c5ff0bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -808,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, | |||
808 | } | 808 | } |
809 | } | 809 | } |
810 | 810 | ||
811 | /* | ||
812 | * The above algorithm sometimes fails when the ucode | ||
813 | * reports 0 for all chains. It's not clear why that | ||
814 | * happens to start with, but it is then causing trouble | ||
815 | * because this can make us enable more chains than the | ||
816 | * hardware really has. | ||
817 | * | ||
818 | * To be safe, simply mask out any chains that we know | ||
819 | * are not on the device. | ||
820 | */ | ||
821 | active_chains &= priv->hw_params.valid_rx_ant; | ||
822 | |||
811 | num_tx_chains = 0; | 823 | num_tx_chains = 0; |
812 | for (i = 0; i < NUM_RX_CHAINS; i++) { | 824 | for (i = 0; i < NUM_RX_CHAINS; i++) { |
813 | /* loops on all the bits of | 825 | /* loops on all the bits of |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index db050b811232..3352f7086632 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -308,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv) | |||
308 | 308 | ||
309 | spin_unlock_irqrestore(&priv->lock, flags); | 309 | spin_unlock_irqrestore(&priv->lock, flags); |
310 | 310 | ||
311 | /* Allocate and init all Tx and Command queues */ | 311 | /* Allocate or reset and init all Tx and Command queues */ |
312 | ret = iwl_txq_ctx_reset(priv); | 312 | if (!priv->txq) { |
313 | if (ret) | 313 | ret = iwl_txq_ctx_alloc(priv); |
314 | return ret; | 314 | if (ret) |
315 | return ret; | ||
316 | } else | ||
317 | iwl_txq_ctx_reset(priv); | ||
315 | 318 | ||
316 | set_bit(STATUS_INIT, &priv->status); | 319 | set_bit(STATUS_INIT, &priv->status); |
317 | 320 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4ef7739f9e8e..732590f5fe30 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); | |||
442 | /***************************************************** | 442 | /***************************************************** |
443 | * TX | 443 | * TX |
444 | ******************************************************/ | 444 | ******************************************************/ |
445 | int iwl_txq_ctx_reset(struct iwl_priv *priv); | 445 | int iwl_txq_ctx_alloc(struct iwl_priv *priv); |
446 | void iwl_txq_ctx_reset(struct iwl_priv *priv); | ||
446 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 447 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
447 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | 448 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, |
448 | struct iwl_tx_queue *txq, | 449 | struct iwl_tx_queue *txq, |
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, | |||
456 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 457 | void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
457 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 458 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
458 | int slots_num, u32 txq_id); | 459 | int slots_num, u32 txq_id); |
460 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
461 | int slots_num, u32 txq_id); | ||
459 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 462 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); |
460 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); | 463 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); |
461 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); | 464 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index f0b7e6cfbe4f..8dd0c036d547 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -194,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv) | |||
194 | struct iwl_queue *q = &txq->q; | 194 | struct iwl_queue *q = &txq->q; |
195 | struct device *dev = &priv->pci_dev->dev; | 195 | struct device *dev = &priv->pci_dev->dev; |
196 | int i; | 196 | int i; |
197 | bool huge = false; | ||
197 | 198 | ||
198 | if (q->n_bd == 0) | 199 | if (q->n_bd == 0) |
199 | return; | 200 | return; |
200 | 201 | ||
202 | for (; q->read_ptr != q->write_ptr; | ||
203 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
204 | /* we have no way to tell if it is a huge cmd ATM */ | ||
205 | i = get_cmd_index(q, q->read_ptr, 0); | ||
206 | |||
207 | if (txq->meta[i].flags & CMD_SIZE_HUGE) { | ||
208 | huge = true; | ||
209 | continue; | ||
210 | } | ||
211 | |||
212 | pci_unmap_single(priv->pci_dev, | ||
213 | pci_unmap_addr(&txq->meta[i], mapping), | ||
214 | pci_unmap_len(&txq->meta[i], len), | ||
215 | PCI_DMA_BIDIRECTIONAL); | ||
216 | } | ||
217 | if (huge) { | ||
218 | i = q->n_window; | ||
219 | pci_unmap_single(priv->pci_dev, | ||
220 | pci_unmap_addr(&txq->meta[i], mapping), | ||
221 | pci_unmap_len(&txq->meta[i], len), | ||
222 | PCI_DMA_BIDIRECTIONAL); | ||
223 | } | ||
224 | |||
201 | /* De-alloc array of command/tx buffers */ | 225 | /* De-alloc array of command/tx buffers */ |
202 | for (i = 0; i <= TFD_CMD_SLOTS; i++) | 226 | for (i = 0; i <= TFD_CMD_SLOTS; i++) |
203 | kfree(txq->cmd[i]); | 227 | kfree(txq->cmd[i]); |
@@ -410,6 +434,26 @@ out_free_arrays: | |||
410 | } | 434 | } |
411 | EXPORT_SYMBOL(iwl_tx_queue_init); | 435 | EXPORT_SYMBOL(iwl_tx_queue_init); |
412 | 436 | ||
437 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
438 | int slots_num, u32 txq_id) | ||
439 | { | ||
440 | int actual_slots = slots_num; | ||
441 | |||
442 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
443 | actual_slots++; | ||
444 | |||
445 | memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); | ||
446 | |||
447 | txq->need_update = 0; | ||
448 | |||
449 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
450 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
451 | |||
452 | /* Tell device where to find queue */ | ||
453 | priv->cfg->ops->lib->txq_init(priv, txq); | ||
454 | } | ||
455 | EXPORT_SYMBOL(iwl_tx_queue_reset); | ||
456 | |||
413 | /** | 457 | /** |
414 | * iwl_hw_txq_ctx_free - Free TXQ Context | 458 | * iwl_hw_txq_ctx_free - Free TXQ Context |
415 | * | 459 | * |
@@ -421,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
421 | 465 | ||
422 | /* Tx queues */ | 466 | /* Tx queues */ |
423 | if (priv->txq) { | 467 | if (priv->txq) { |
424 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; | 468 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) |
425 | txq_id++) | ||
426 | if (txq_id == IWL_CMD_QUEUE_NUM) | 469 | if (txq_id == IWL_CMD_QUEUE_NUM) |
427 | iwl_cmd_queue_free(priv); | 470 | iwl_cmd_queue_free(priv); |
428 | else | 471 | else |
@@ -438,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | |||
438 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 481 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); |
439 | 482 | ||
440 | /** | 483 | /** |
441 | * iwl_txq_ctx_reset - Reset TX queue context | 484 | * iwl_txq_ctx_alloc - allocate TX queue context |
442 | * Destroys all DMA structures and initialize them again | 485 | * Allocate all Tx DMA structures and initialize them |
443 | * | 486 | * |
444 | * @param priv | 487 | * @param priv |
445 | * @return error code | 488 | * @return error code |
446 | */ | 489 | */ |
447 | int iwl_txq_ctx_reset(struct iwl_priv *priv) | 490 | int iwl_txq_ctx_alloc(struct iwl_priv *priv) |
448 | { | 491 | { |
449 | int ret = 0; | 492 | int ret; |
450 | int txq_id, slots_num; | 493 | int txq_id, slots_num; |
451 | unsigned long flags; | 494 | unsigned long flags; |
452 | 495 | ||
@@ -504,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
504 | return ret; | 547 | return ret; |
505 | } | 548 | } |
506 | 549 | ||
550 | void iwl_txq_ctx_reset(struct iwl_priv *priv) | ||
551 | { | ||
552 | int txq_id, slots_num; | ||
553 | unsigned long flags; | ||
554 | |||
555 | spin_lock_irqsave(&priv->lock, flags); | ||
556 | |||
557 | /* Turn off all Tx DMA fifos */ | ||
558 | priv->cfg->ops->lib->txq_set_sched(priv, 0); | ||
559 | |||
560 | /* Tell NIC where to find the "keep warm" buffer */ | ||
561 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); | ||
562 | |||
563 | spin_unlock_irqrestore(&priv->lock, flags); | ||
564 | |||
565 | /* Alloc and init all Tx queues, including the command queue (#4) */ | ||
566 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
567 | slots_num = txq_id == IWL_CMD_QUEUE_NUM ? | ||
568 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
569 | iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); | ||
570 | } | ||
571 | } | ||
572 | |||
507 | /** | 573 | /** |
508 | * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory | 574 | * iwl_txq_ctx_stop - Stop all Tx DMA channels |
509 | */ | 575 | */ |
510 | void iwl_txq_ctx_stop(struct iwl_priv *priv) | 576 | void iwl_txq_ctx_stop(struct iwl_priv *priv) |
511 | { | 577 | { |
@@ -525,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv) | |||
525 | 1000); | 591 | 1000); |
526 | } | 592 | } |
527 | spin_unlock_irqrestore(&priv->lock, flags); | 593 | spin_unlock_irqrestore(&priv->lock, flags); |
528 | |||
529 | /* Deallocate memory for all Tx queues */ | ||
530 | iwl_hw_txq_ctx_free(priv); | ||
531 | } | 594 | } |
532 | EXPORT_SYMBOL(iwl_txq_ctx_stop); | 595 | EXPORT_SYMBOL(iwl_txq_ctx_stop); |
533 | 596 | ||
@@ -1050,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1050 | 1113 | ||
1051 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 1114 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
1052 | 1115 | ||
1116 | /* If this is a huge cmd, mark the huge flag also on the meta.flags | ||
1117 | * of the _original_ cmd. This is used for DMA mapping clean up. | ||
1118 | */ | ||
1119 | if (cmd->flags & CMD_SIZE_HUGE) { | ||
1120 | idx = get_cmd_index(q, q->write_ptr, 0); | ||
1121 | txq->meta[idx].flags = CMD_SIZE_HUGE; | ||
1122 | } | ||
1123 | |||
1053 | idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); | 1124 | idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); |
1054 | out_cmd = txq->cmd[idx]; | 1125 | out_cmd = txq->cmd[idx]; |
1055 | out_meta = &txq->meta[idx]; | 1126 | out_meta = &txq->meta[idx]; |
@@ -1227,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1227 | bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); | 1298 | bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); |
1228 | struct iwl_device_cmd *cmd; | 1299 | struct iwl_device_cmd *cmd; |
1229 | struct iwl_cmd_meta *meta; | 1300 | struct iwl_cmd_meta *meta; |
1301 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | ||
1230 | 1302 | ||
1231 | /* If a Tx command is being handled and it isn't in the actual | 1303 | /* If a Tx command is being handled and it isn't in the actual |
1232 | * command queue then there a command routing bug has been introduced | 1304 | * command queue then there a command routing bug has been introduced |
@@ -1240,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1240 | return; | 1312 | return; |
1241 | } | 1313 | } |
1242 | 1314 | ||
1243 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); | 1315 | /* If this is a huge cmd, clear the huge flag on the meta.flags |
1244 | cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; | 1316 | * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap |
1245 | meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index]; | 1317 | * the DMA buffer for the scan (huge) command. |
1318 | */ | ||
1319 | if (huge) { | ||
1320 | cmd_index = get_cmd_index(&txq->q, index, 0); | ||
1321 | txq->meta[cmd_index].flags = 0; | ||
1322 | } | ||
1323 | cmd_index = get_cmd_index(&txq->q, index, huge); | ||
1324 | cmd = txq->cmd[cmd_index]; | ||
1325 | meta = &txq->meta[cmd_index]; | ||
1246 | 1326 | ||
1247 | pci_unmap_single(priv->pci_dev, | 1327 | pci_unmap_single(priv->pci_dev, |
1248 | pci_unmap_addr(meta, mapping), | 1328 | pci_unmap_addr(meta, mapping), |
@@ -1264,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1264 | get_cmd_string(cmd->hdr.cmd)); | 1344 | get_cmd_string(cmd->hdr.cmd)); |
1265 | wake_up_interruptible(&priv->wait_command_queue); | 1345 | wake_up_interruptible(&priv->wait_command_queue); |
1266 | } | 1346 | } |
1347 | meta->flags = 0; | ||
1267 | } | 1348 | } |
1268 | EXPORT_SYMBOL(iwl_tx_cmd_complete); | 1349 | EXPORT_SYMBOL(iwl_tx_cmd_complete); |
1269 | 1350 | ||
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index f230f6543bff..854959cada3a 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) | |||
1484 | if (!s) | 1484 | if (!s) |
1485 | return -EINVAL; | 1485 | return -EINVAL; |
1486 | 1486 | ||
1487 | if (s->functions) { | ||
1488 | WARN_ON(1); | ||
1489 | return -EINVAL; | ||
1490 | } | ||
1491 | |||
1487 | /* We do not want to validate the CIS cache... */ | 1492 | /* We do not want to validate the CIS cache... */ |
1488 | mutex_lock(&s->ops_mutex); | 1493 | mutex_lock(&s->ops_mutex); |
1489 | destroy_cis_cache(s); | 1494 | destroy_cis_cache(s); |
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, | |||
1639 | count = 0; | 1644 | count = 0; |
1640 | else { | 1645 | else { |
1641 | struct pcmcia_socket *s; | 1646 | struct pcmcia_socket *s; |
1642 | unsigned int chains; | 1647 | unsigned int chains = 1; |
1643 | 1648 | ||
1644 | if (off + count > size) | 1649 | if (off + count > size) |
1645 | count = size - off; | 1650 | count = size - off; |
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, | |||
1648 | 1653 | ||
1649 | if (!(s->state & SOCKET_PRESENT)) | 1654 | if (!(s->state & SOCKET_PRESENT)) |
1650 | return -ENODEV; | 1655 | return -ENODEV; |
1651 | if (pccard_validate_cis(s, &chains)) | 1656 | if (!s->functions && pccard_validate_cis(s, &chains)) |
1652 | return -EIO; | 1657 | return -EIO; |
1653 | if (!chains) | 1658 | if (!chains) |
1654 | return -ENODATA; | 1659 | return -ENODATA; |
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 6206408e196c..2d48196a48cd 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c | |||
@@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) | |||
166 | 166 | ||
167 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, | 167 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, |
168 | IRQF_DISABLED, "pcmcia_insert", sock); | 168 | IRQF_DISABLED, "pcmcia_insert", sock); |
169 | if (ret) | 169 | if (ret) { |
170 | local_irq_restore(flags); | ||
170 | goto out1; | 171 | goto out1; |
172 | } | ||
171 | 173 | ||
172 | ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, | 174 | ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, |
173 | IRQF_DISABLED, "pcmcia_eject", sock); | 175 | IRQF_DISABLED, "pcmcia_eject", sock); |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cb6036d89e59..4014cf8e4a26 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) | |||
687 | new_funcs = mfc.nfn; | 687 | new_funcs = mfc.nfn; |
688 | else | 688 | else |
689 | new_funcs = 1; | 689 | new_funcs = 1; |
690 | if (old_funcs > new_funcs) { | 690 | if (old_funcs != new_funcs) { |
691 | /* we need to re-start */ | ||
691 | pcmcia_card_remove(s, NULL); | 692 | pcmcia_card_remove(s, NULL); |
692 | pcmcia_card_add(s); | 693 | pcmcia_card_add(s); |
693 | } else if (new_funcs > old_funcs) { | ||
694 | s->functions = new_funcs; | ||
695 | pcmcia_device_add(s, 1); | ||
696 | } | 694 | } |
697 | } | 695 | } |
698 | 696 | ||
@@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
728 | struct pcmcia_socket *s = dev->socket; | 726 | struct pcmcia_socket *s = dev->socket; |
729 | const struct firmware *fw; | 727 | const struct firmware *fw; |
730 | int ret = -ENOMEM; | 728 | int ret = -ENOMEM; |
729 | cistpl_longlink_mfc_t mfc; | ||
730 | int old_funcs, new_funcs = 1; | ||
731 | 731 | ||
732 | if (!filename) | 732 | if (!filename) |
733 | return -EINVAL; | 733 | return -EINVAL; |
@@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
750 | goto release; | 750 | goto release; |
751 | } | 751 | } |
752 | 752 | ||
753 | /* we need to re-start if the number of functions changed */ | ||
754 | old_funcs = s->functions; | ||
755 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, | ||
756 | &mfc)) | ||
757 | new_funcs = mfc.nfn; | ||
758 | |||
759 | if (old_funcs != new_funcs) | ||
760 | ret = -EBUSY; | ||
753 | 761 | ||
754 | /* update information */ | 762 | /* update information */ |
755 | pcmcia_device_query(dev); | 763 | pcmcia_device_query(dev); |
@@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
858 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 866 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
859 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); | 867 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); |
860 | if (!dev->socket->fake_cis) | 868 | if (!dev->socket->fake_cis) |
861 | pcmcia_load_firmware(dev, did->cisfile); | 869 | if (pcmcia_load_firmware(dev, did->cisfile)) |
862 | 870 | return 0; | |
863 | if (!dev->socket->fake_cis) | ||
864 | return 0; | ||
865 | } | 871 | } |
866 | 872 | ||
867 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { | 873 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index caec1dee2a4b..7c3d03bb4f30 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
755 | else | 755 | else |
756 | printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); | 756 | printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); |
757 | 757 | ||
758 | #ifdef CONFIG_PCMCIA_PROBE | 758 | /* If the interrupt is already assigned, it must be the same */ |
759 | 759 | if (s->irq.AssignedIRQ != 0) | |
760 | if (s->irq.AssignedIRQ != 0) { | ||
761 | /* If the interrupt is already assigned, it must be the same */ | ||
762 | irq = s->irq.AssignedIRQ; | 760 | irq = s->irq.AssignedIRQ; |
763 | } else { | 761 | |
762 | #ifdef CONFIG_PCMCIA_PROBE | ||
763 | if (!irq) { | ||
764 | int try; | 764 | int try; |
765 | u32 mask = s->irq_mask; | 765 | u32 mask = s->irq_mask; |
766 | void *data = p_dev; /* something unique to this device */ | 766 | void *data = p_dev; /* something unique to this device */ |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 559069a80a3b..a6eb7b59ba9f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
214 | return; | 214 | return; |
215 | } | 215 | } |
216 | for (i = base, most = 0; i < base+num; i += 8) { | 216 | for (i = base, most = 0; i < base+num; i += 8) { |
217 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); | 217 | res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); |
218 | if (!res) | 218 | if (!res) |
219 | continue; | 219 | continue; |
220 | hole = inb(i); | 220 | hole = inb(i); |
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
231 | 231 | ||
232 | bad = any = 0; | 232 | bad = any = 0; |
233 | for (i = base; i < base+num; i += 8) { | 233 | for (i = base; i < base+num; i += 8) { |
234 | res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); | 234 | res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); |
235 | if (!res) | 235 | if (!res) { |
236 | if (!any) | ||
237 | printk(" excluding"); | ||
238 | if (!bad) | ||
239 | bad = any = i; | ||
236 | continue; | 240 | continue; |
241 | } | ||
237 | for (j = 0; j < 8; j++) | 242 | for (j = 0; j < 8; j++) |
238 | if (inb(i+j) != most) | 243 | if (inb(i+j) != most) |
239 | break; | 244 | break; |
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base, | |||
253 | } | 258 | } |
254 | if (bad) { | 259 | if (bad) { |
255 | if ((num > 16) && (bad == base) && (i == base+num)) { | 260 | if ((num > 16) && (bad == base) && (i == base+num)) { |
261 | sub_interval(&s_data->io_db, bad, i-bad); | ||
256 | printk(" nothing: probe failed.\n"); | 262 | printk(" nothing: probe failed.\n"); |
257 | return; | 263 | return; |
258 | } else { | 264 | } else { |
@@ -804,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned | |||
804 | static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) | 810 | static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) |
805 | { | 811 | { |
806 | struct socket_data *data = s->resource_data; | 812 | struct socket_data *data = s->resource_data; |
807 | unsigned long size = end - start + 1; | 813 | unsigned long size; |
808 | int ret = 0; | 814 | int ret = 0; |
809 | 815 | ||
810 | #if defined(CONFIG_X86) | 816 | #if defined(CONFIG_X86) |
@@ -814,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long | |||
814 | start = 0x100; | 820 | start = 0x100; |
815 | #endif | 821 | #endif |
816 | 822 | ||
823 | size = end - start + 1; | ||
824 | |||
817 | if (end < start) | 825 | if (end < start) |
818 | return -EINVAL; | 826 | return -EINVAL; |
819 | 827 | ||
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index c6c552f681b7..35bb44af49b3 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -274,12 +274,33 @@ static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev, | |||
274 | pnp_add_bus_resource(dev, start, end); | 274 | pnp_add_bus_resource(dev, start, end); |
275 | } | 275 | } |
276 | 276 | ||
277 | static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len) | ||
278 | { | ||
279 | u64 max_len; | ||
280 | |||
281 | max_len = max - min + 1; | ||
282 | if (len <= max_len) | ||
283 | return len; | ||
284 | |||
285 | /* | ||
286 | * Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes | ||
287 | * don't do this correctly, e.g., | ||
288 | * https://bugzilla.kernel.org/show_bug.cgi?id=15480 | ||
289 | */ | ||
290 | dev_info(&dev->dev, | ||
291 | "resource length %#llx doesn't fit in %#llx-%#llx, trimming\n", | ||
292 | (unsigned long long) len, (unsigned long long) min, | ||
293 | (unsigned long long) max); | ||
294 | return max_len; | ||
295 | } | ||
296 | |||
277 | static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, | 297 | static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, |
278 | struct acpi_resource *res) | 298 | struct acpi_resource *res) |
279 | { | 299 | { |
280 | struct acpi_resource_address64 addr, *p = &addr; | 300 | struct acpi_resource_address64 addr, *p = &addr; |
281 | acpi_status status; | 301 | acpi_status status; |
282 | int window; | 302 | int window; |
303 | u64 len; | ||
283 | 304 | ||
284 | status = acpi_resource_to_address64(res, p); | 305 | status = acpi_resource_to_address64(res, p); |
285 | if (!ACPI_SUCCESS(status)) { | 306 | if (!ACPI_SUCCESS(status)) { |
@@ -288,20 +309,18 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, | |||
288 | return; | 309 | return; |
289 | } | 310 | } |
290 | 311 | ||
312 | len = addr_space_length(dev, p->minimum, p->maximum, p->address_length); | ||
291 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; | 313 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; |
292 | 314 | ||
293 | if (p->resource_type == ACPI_MEMORY_RANGE) | 315 | if (p->resource_type == ACPI_MEMORY_RANGE) |
294 | pnpacpi_parse_allocated_memresource(dev, | 316 | pnpacpi_parse_allocated_memresource(dev, p->minimum, len, |
295 | p->minimum, p->address_length, | ||
296 | p->info.mem.write_protect, window); | 317 | p->info.mem.write_protect, window); |
297 | else if (p->resource_type == ACPI_IO_RANGE) | 318 | else if (p->resource_type == ACPI_IO_RANGE) |
298 | pnpacpi_parse_allocated_ioresource(dev, | 319 | pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, |
299 | p->minimum, p->address_length, | ||
300 | p->granularity == 0xfff ? ACPI_DECODE_10 : | 320 | p->granularity == 0xfff ? ACPI_DECODE_10 : |
301 | ACPI_DECODE_16, window); | 321 | ACPI_DECODE_16, window); |
302 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) | 322 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) |
303 | pnpacpi_parse_allocated_busresource(dev, p->minimum, | 323 | pnpacpi_parse_allocated_busresource(dev, p->minimum, len); |
304 | p->address_length); | ||
305 | } | 324 | } |
306 | 325 | ||
307 | static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, | 326 | static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, |
@@ -309,21 +328,20 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, | |||
309 | { | 328 | { |
310 | struct acpi_resource_extended_address64 *p = &res->data.ext_address64; | 329 | struct acpi_resource_extended_address64 *p = &res->data.ext_address64; |
311 | int window; | 330 | int window; |
331 | u64 len; | ||
312 | 332 | ||
333 | len = addr_space_length(dev, p->minimum, p->maximum, p->address_length); | ||
313 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; | 334 | window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; |
314 | 335 | ||
315 | if (p->resource_type == ACPI_MEMORY_RANGE) | 336 | if (p->resource_type == ACPI_MEMORY_RANGE) |
316 | pnpacpi_parse_allocated_memresource(dev, | 337 | pnpacpi_parse_allocated_memresource(dev, p->minimum, len, |
317 | p->minimum, p->address_length, | ||
318 | p->info.mem.write_protect, window); | 338 | p->info.mem.write_protect, window); |
319 | else if (p->resource_type == ACPI_IO_RANGE) | 339 | else if (p->resource_type == ACPI_IO_RANGE) |
320 | pnpacpi_parse_allocated_ioresource(dev, | 340 | pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, |
321 | p->minimum, p->address_length, | ||
322 | p->granularity == 0xfff ? ACPI_DECODE_10 : | 341 | p->granularity == 0xfff ? ACPI_DECODE_10 : |
323 | ACPI_DECODE_16, window); | 342 | ACPI_DECODE_16, window); |
324 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) | 343 | else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) |
325 | pnpacpi_parse_allocated_busresource(dev, p->minimum, | 344 | pnpacpi_parse_allocated_busresource(dev, p->minimum, len); |
326 | p->address_length); | ||
327 | } | 345 | } |
328 | 346 | ||
329 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | 347 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, |
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index a681f5e8f786..ad036dd8da13 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c | |||
@@ -618,9 +618,12 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev) | |||
618 | dev_get_platdata(&pdev->dev); | 618 | dev_get_platdata(&pdev->dev); |
619 | int i; | 619 | int i; |
620 | 620 | ||
621 | platform_set_drvdata(pdev, NULL); | ||
622 | |||
621 | for (i = 0; i < pdata->num_regulators; i++) | 623 | for (i = 0; i < pdata->num_regulators; i++) |
622 | regulator_unregister(priv->regulators[i]); | 624 | regulator_unregister(priv->regulators[i]); |
623 | 625 | ||
626 | kfree(priv); | ||
624 | return 0; | 627 | return 0; |
625 | } | 628 | } |
626 | 629 | ||
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index 2aecf7f21361..7ad30e72f868 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c | |||
@@ -85,7 +85,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, | |||
85 | rc = copy_from_user(buf, buffer, sizeof(buf)); | 85 | rc = copy_from_user(buf, buffer, sizeof(buf)); |
86 | if (rc != 0) | 86 | if (rc != 0) |
87 | return -EFAULT; | 87 | return -EFAULT; |
88 | buf[len - 1] = '\0'; | 88 | buf[sizeof(buf) - 1] = '\0'; |
89 | if (strict_strtoul(buf, 0, &val) != 0) | 89 | if (strict_strtoul(buf, 0, &val) != 0) |
90 | return -EINVAL; | 90 | return -EINVAL; |
91 | if (val != 0 && val != 1) | 91 | if (val != 0 && val != 1) |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 58c62ff42ab3..8b827f37b03e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2186,7 +2186,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2186 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | 2186 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); |
2187 | 2187 | ||
2188 | gd->driverfs_dev = &sdp->sdev_gendev; | 2188 | gd->driverfs_dev = &sdp->sdev_gendev; |
2189 | gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; | 2189 | gd->flags = GENHD_FL_EXT_DEVT; |
2190 | if (sdp->removable) | 2190 | if (sdp->removable) |
2191 | gd->flags |= GENHD_FL_REMOVABLE; | 2191 | gd->flags |= GENHD_FL_REMOVABLE; |
2192 | 2192 | ||
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c index 7bb5fee639e3..b5aaef965f24 100644 --- a/drivers/serial/mcf.c +++ b/drivers/serial/mcf.c | |||
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | spin_lock_irqsave(&port->lock, flags); | 265 | spin_lock_irqsave(&port->lock, flags); |
266 | uart_update_timeout(port, termios->c_cflag, baud); | ||
266 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); | 267 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
267 | writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); | 268 | writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); |
268 | writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); | 269 | writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); |
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data) | |||
379 | static void mcf_config_port(struct uart_port *port, int flags) | 380 | static void mcf_config_port(struct uart_port *port, int flags) |
380 | { | 381 | { |
381 | port->type = PORT_MCF; | 382 | port->type = PORT_MCF; |
383 | port->fifosize = MCFUART_TXFIFOSIZE; | ||
382 | 384 | ||
383 | /* Clear mask, so no surprise interrupts. */ | 385 | /* Clear mask, so no surprise interrupts. */ |
384 | writeb(0, port->membase + MCFUART_UIMR); | 386 | writeb(0, port->membase + MCFUART_UIMR); |
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
424 | /* | 426 | /* |
425 | * Define the basic serial functions we support. | 427 | * Define the basic serial functions we support. |
426 | */ | 428 | */ |
427 | static struct uart_ops mcf_uart_ops = { | 429 | static const struct uart_ops mcf_uart_ops = { |
428 | .tx_empty = mcf_tx_empty, | 430 | .tx_empty = mcf_tx_empty, |
429 | .get_mctrl = mcf_get_mctrl, | 431 | .get_mctrl = mcf_get_mctrl, |
430 | .set_mctrl = mcf_set_mctrl, | 432 | .set_mctrl = mcf_set_mctrl, |
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = { | |||
443 | .verify_port = mcf_verify_port, | 445 | .verify_port = mcf_verify_port, |
444 | }; | 446 | }; |
445 | 447 | ||
446 | static struct mcf_uart mcf_ports[3]; | 448 | static struct mcf_uart mcf_ports[4]; |
447 | 449 | ||
448 | #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) | 450 | #define MCF_MAXPORTS ARRAY_SIZE(mcf_ports) |
449 | 451 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 175d202ab37e..8cfa5b12ea7a 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -105,6 +105,10 @@ struct serial_cfg_mem { | |||
105 | * manfid 0x0160, 0x0104 | 105 | * manfid 0x0160, 0x0104 |
106 | * This card appears to have a 14.7456MHz clock. | 106 | * This card appears to have a 14.7456MHz clock. |
107 | */ | 107 | */ |
108 | /* Generic Modem: MD55x (GPRS/EDGE) have | ||
109 | * Elan VPU16551 UART with 14.7456MHz oscillator | ||
110 | * manfid 0x015D, 0x4C45 | ||
111 | */ | ||
108 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) | 112 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) |
109 | { | 113 | { |
110 | port->uartclk = 14745600; | 114 | port->uartclk = 14745600; |
@@ -196,6 +200,11 @@ static const struct serial_quirk quirks[] = { | |||
196 | .multi = -1, | 200 | .multi = -1, |
197 | .setup = quirk_setup_brainboxes_0104, | 201 | .setup = quirk_setup_brainboxes_0104, |
198 | }, { | 202 | }, { |
203 | .manfid = 0x015D, | ||
204 | .prodid = 0x4C45, | ||
205 | .multi = -1, | ||
206 | .setup = quirk_setup_brainboxes_0104, | ||
207 | }, { | ||
199 | .manfid = MANFID_IBM, | 208 | .manfid = MANFID_IBM, |
200 | .prodid = ~0, | 209 | .prodid = ~0, |
201 | .multi = -1, | 210 | .multi = -1, |
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index f1dcd7969a5c..0e8d35224614 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = { | |||
246 | .pci_ops = &ssb_pcicore_pciops, | 246 | .pci_ops = &ssb_pcicore_pciops, |
247 | .io_resource = &ssb_pcicore_io_resource, | 247 | .io_resource = &ssb_pcicore_io_resource, |
248 | .mem_resource = &ssb_pcicore_mem_resource, | 248 | .mem_resource = &ssb_pcicore_mem_resource, |
249 | .mem_offset = 0x24000000, | ||
250 | }; | 249 | }; |
251 | 250 | ||
252 | static u32 ssb_pcicore_pcibus_iobase = 0x100; | ||
253 | static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA; | ||
254 | |||
255 | /* This function is called when doing a pci_enable_device(). | 251 | /* This function is called when doing a pci_enable_device(). |
256 | * We must first check if the device is a device on the PCI-core bridge. */ | 252 | * We must first check if the device is a device on the PCI-core bridge. */ |
257 | int ssb_pcicore_plat_dev_init(struct pci_dev *d) | 253 | int ssb_pcicore_plat_dev_init(struct pci_dev *d) |
258 | { | 254 | { |
259 | struct resource *res; | ||
260 | int pos, size; | ||
261 | u32 *base; | ||
262 | |||
263 | if (d->bus->ops != &ssb_pcicore_pciops) { | 255 | if (d->bus->ops != &ssb_pcicore_pciops) { |
264 | /* This is not a device on the PCI-core bridge. */ | 256 | /* This is not a device on the PCI-core bridge. */ |
265 | return -ENODEV; | 257 | return -ENODEV; |
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d) | |||
268 | ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", | 260 | ssb_printk(KERN_INFO "PCI: Fixing up device %s\n", |
269 | pci_name(d)); | 261 | pci_name(d)); |
270 | 262 | ||
271 | /* Fix up resource bases */ | ||
272 | for (pos = 0; pos < 6; pos++) { | ||
273 | res = &d->resource[pos]; | ||
274 | if (res->flags & IORESOURCE_IO) | ||
275 | base = &ssb_pcicore_pcibus_iobase; | ||
276 | else | ||
277 | base = &ssb_pcicore_pcibus_membase; | ||
278 | res->flags |= IORESOURCE_PCI_FIXED; | ||
279 | if (res->end) { | ||
280 | size = res->end - res->start + 1; | ||
281 | if (*base & (size - 1)) | ||
282 | *base = (*base + size) & ~(size - 1); | ||
283 | res->start = *base; | ||
284 | res->end = res->start + size - 1; | ||
285 | *base += size; | ||
286 | pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); | ||
287 | } | ||
288 | /* Fix up PCI bridge BAR0 only */ | ||
289 | if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0) | ||
290 | break; | ||
291 | } | ||
292 | /* Fix up interrupt lines */ | 263 | /* Fix up interrupt lines */ |
293 | d->irq = ssb_mips_irq(extpci_core->dev) + 2; | 264 | d->irq = ssb_mips_irq(extpci_core->dev) + 2; |
294 | pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); | 265 | pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 5be11c99e18f..e69d238c5af0 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -236,6 +236,10 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem, | |||
236 | int log_all) | 236 | int log_all) |
237 | { | 237 | { |
238 | int i; | 238 | int i; |
239 | |||
240 | if (!mem) | ||
241 | return 0; | ||
242 | |||
239 | for (i = 0; i < mem->nregions; ++i) { | 243 | for (i = 0; i < mem->nregions; ++i) { |
240 | struct vhost_memory_region *m = mem->regions + i; | 244 | struct vhost_memory_region *m = mem->regions + i; |
241 | unsigned long a = m->userspace_addr; | 245 | unsigned long a = m->userspace_addr; |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0e8468ffd100..0bf5020d0d32 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG | |||
194 | 194 | ||
195 | config OMAP_WATCHDOG | 195 | config OMAP_WATCHDOG |
196 | tristate "OMAP Watchdog" | 196 | tristate "OMAP Watchdog" |
197 | depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3 | 197 | depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS |
198 | help | 198 | help |
199 | Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' | 199 | Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog. Say 'Y' |
200 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. | 200 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. |
201 | 201 | ||
202 | config PNX4008_WATCHDOG | 202 | config PNX4008_WATCHDOG |
203 | tristate "PNX4008 Watchdog" | 203 | tristate "PNX4008 Watchdog" |
@@ -302,7 +302,7 @@ config TS72XX_WATCHDOG | |||
302 | 302 | ||
303 | config MAX63XX_WATCHDOG | 303 | config MAX63XX_WATCHDOG |
304 | tristate "Max63xx watchdog" | 304 | tristate "Max63xx watchdog" |
305 | depends on ARM | 305 | depends on ARM && HAS_IOMEM |
306 | help | 306 | help |
307 | Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. | 307 | Support for memory mapped max63{69,70,71,72,73,74} watchdog timer. |
308 | 308 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 8b724aad6825..500d38342e1e 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | |||
44 | 44 | ||
45 | #ifdef CONFIG_FSL_BOOKE | 45 | #ifdef CONFIG_FSL_BOOKE |
46 | #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) | 46 | #define WDTP(x) ((((x)&0x3)<<30)|(((x)&0x3c)<<15)) |
47 | #define WDTP_MASK (WDTP(0)) | 47 | #define WDTP_MASK (WDTP(0x3f)) |
48 | #else | 48 | #else |
49 | #define WDTP(x) (TCR_WP(x)) | 49 | #define WDTP(x) (TCR_WP(x)) |
50 | #define WDTP_MASK (TCR_WP_MASK) | 50 | #define WDTP_MASK (TCR_WP_MASK) |
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index 75f3a83c0361..3053ff05ca41 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c | |||
@@ -154,9 +154,14 @@ static void max63xx_wdt_enable(struct max63xx_timeout *entry) | |||
154 | 154 | ||
155 | static void max63xx_wdt_disable(void) | 155 | static void max63xx_wdt_disable(void) |
156 | { | 156 | { |
157 | u8 val; | ||
158 | |||
157 | spin_lock(&io_lock); | 159 | spin_lock(&io_lock); |
158 | 160 | ||
159 | __raw_writeb(3, wdt_base); | 161 | val = __raw_readb(wdt_base); |
162 | val &= ~MAX6369_WDSET; | ||
163 | val |= 3; | ||
164 | __raw_writeb(val, wdt_base); | ||
160 | 165 | ||
161 | spin_unlock(&io_lock); | 166 | spin_unlock(&io_lock); |
162 | 167 | ||
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index 5e813a816ce4..b3feddc4f7d6 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) | |||
138 | { | 138 | { |
139 | struct afs_super_info *super; | 139 | struct afs_super_info *super; |
140 | struct vfsmount *mnt; | 140 | struct vfsmount *mnt; |
141 | struct page *page = NULL; | 141 | struct page *page; |
142 | size_t size; | 142 | size_t size; |
143 | char *buf, *devname = NULL, *options = NULL; | 143 | char *buf, *devname, *options; |
144 | int ret; | 144 | int ret; |
145 | 145 | ||
146 | _enter("{%s}", mntpt->d_name.name); | 146 | _enter("{%s}", mntpt->d_name.name); |
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) | |||
150 | ret = -EINVAL; | 150 | ret = -EINVAL; |
151 | size = mntpt->d_inode->i_size; | 151 | size = mntpt->d_inode->i_size; |
152 | if (size > PAGE_SIZE - 1) | 152 | if (size > PAGE_SIZE - 1) |
153 | goto error; | 153 | goto error_no_devname; |
154 | 154 | ||
155 | ret = -ENOMEM; | 155 | ret = -ENOMEM; |
156 | devname = (char *) get_zeroed_page(GFP_KERNEL); | 156 | devname = (char *) get_zeroed_page(GFP_KERNEL); |
157 | if (!devname) | 157 | if (!devname) |
158 | goto error; | 158 | goto error_no_devname; |
159 | 159 | ||
160 | options = (char *) get_zeroed_page(GFP_KERNEL); | 160 | options = (char *) get_zeroed_page(GFP_KERNEL); |
161 | if (!options) | 161 | if (!options) |
162 | goto error; | 162 | goto error_no_options; |
163 | 163 | ||
164 | /* read the contents of the AFS special symlink */ | 164 | /* read the contents of the AFS special symlink */ |
165 | page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL); | 165 | page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL); |
166 | if (IS_ERR(page)) { | 166 | if (IS_ERR(page)) { |
167 | ret = PTR_ERR(page); | 167 | ret = PTR_ERR(page); |
168 | goto error; | 168 | goto error_no_page; |
169 | } | 169 | } |
170 | 170 | ||
171 | ret = -EIO; | 171 | ret = -EIO; |
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) | |||
196 | return mnt; | 196 | return mnt; |
197 | 197 | ||
198 | error: | 198 | error: |
199 | if (page) | 199 | page_cache_release(page); |
200 | page_cache_release(page); | 200 | error_no_page: |
201 | if (devname) | 201 | free_page((unsigned long) options); |
202 | free_page((unsigned long) devname); | 202 | error_no_options: |
203 | if (options) | 203 | free_page((unsigned long) devname); |
204 | free_page((unsigned long) options); | 204 | error_no_devname: |
205 | _leave(" = %d", ret); | 205 | _leave(" = %d", ret); |
206 | return ERR_PTR(ret); | 206 | return ERR_PTR(ret); |
207 | } | 207 | } |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index e0e769bdca59..49566c1687d8 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) | |||
355 | 355 | ||
356 | if (!flat_reloc_valid(r, start_brk - start_data + text_len)) { | 356 | if (!flat_reloc_valid(r, start_brk - start_data + text_len)) { |
357 | printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)", | 357 | printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)", |
358 | (int) r,(int)(start_brk-start_code),(int)text_len); | 358 | (int) r,(int)(start_brk-start_data+text_len),(int)text_len); |
359 | goto failed; | 359 | goto failed; |
360 | } | 360 | } |
361 | 361 | ||
@@ -554,7 +554,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
554 | .bi_rw = bio->bi_rw, | 554 | .bi_rw = bio->bi_rw, |
555 | }; | 555 | }; |
556 | 556 | ||
557 | if (q->merge_bvec_fn(q, &bvm, prev) < len) { | 557 | if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) { |
558 | prev->bv_len -= len; | 558 | prev->bv_len -= len; |
559 | return 0; | 559 | return 0; |
560 | } | 560 | } |
@@ -607,7 +607,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
607 | * merge_bvec_fn() returns number of bytes it can accept | 607 | * merge_bvec_fn() returns number of bytes it can accept |
608 | * at this offset | 608 | * at this offset |
609 | */ | 609 | */ |
610 | if (q->merge_bvec_fn(q, &bvm, bvec) < len) { | 610 | if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) { |
611 | bvec->bv_page = NULL; | 611 | bvec->bv_page = NULL; |
612 | bvec->bv_len = 0; | 612 | bvec->bv_len = 0; |
613 | bvec->bv_offset = 0; | 613 | bvec->bv_offset = 0; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9e23ffea7f54..b34d32fdaaec 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | |||
3235 | u64 bytes) | 3235 | u64 bytes) |
3236 | { | 3236 | { |
3237 | struct btrfs_space_info *data_sinfo; | 3237 | struct btrfs_space_info *data_sinfo; |
3238 | int ret = 0, committed = 0; | 3238 | u64 used; |
3239 | int ret = 0, committed = 0, flushed = 0; | ||
3239 | 3240 | ||
3240 | /* make sure bytes are sectorsize aligned */ | 3241 | /* make sure bytes are sectorsize aligned */ |
3241 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 3242 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | |||
3247 | again: | 3248 | again: |
3248 | /* make sure we have enough space to handle the data first */ | 3249 | /* make sure we have enough space to handle the data first */ |
3249 | spin_lock(&data_sinfo->lock); | 3250 | spin_lock(&data_sinfo->lock); |
3250 | if (data_sinfo->total_bytes - data_sinfo->bytes_used - | 3251 | used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc + |
3251 | data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - | 3252 | data_sinfo->bytes_reserved + data_sinfo->bytes_pinned + |
3252 | data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - | 3253 | data_sinfo->bytes_readonly + data_sinfo->bytes_may_use + |
3253 | data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) { | 3254 | data_sinfo->bytes_super; |
3255 | |||
3256 | if (used + bytes > data_sinfo->total_bytes) { | ||
3254 | struct btrfs_trans_handle *trans; | 3257 | struct btrfs_trans_handle *trans; |
3255 | 3258 | ||
3259 | if (!flushed) { | ||
3260 | spin_unlock(&data_sinfo->lock); | ||
3261 | flush_delalloc(root, data_sinfo); | ||
3262 | flushed = 1; | ||
3263 | goto again; | ||
3264 | } | ||
3265 | |||
3256 | /* | 3266 | /* |
3257 | * if we don't have enough free bytes in this space then we need | 3267 | * if we don't have enough free bytes in this space then we need |
3258 | * to alloc a new chunk. | 3268 | * to alloc a new chunk. |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index aa7dc36dac78..8db7b14bbae8 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2250,6 +2250,12 @@ again: | |||
2250 | if (!looped) | 2250 | if (!looped) |
2251 | calc_size = max_t(u64, min_stripe_size, calc_size); | 2251 | calc_size = max_t(u64, min_stripe_size, calc_size); |
2252 | 2252 | ||
2253 | /* | ||
2254 | * we're about to do_div by the stripe_len so lets make sure | ||
2255 | * we end up with something bigger than a stripe | ||
2256 | */ | ||
2257 | calc_size = max_t(u64, calc_size, stripe_len * 4); | ||
2258 | |||
2253 | do_div(calc_size, stripe_len); | 2259 | do_div(calc_size, stripe_len); |
2254 | calc_size *= stripe_len; | 2260 | calc_size *= stripe_len; |
2255 | 2261 | ||
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index aa3cd7cc3e40..412593703d1e 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -337,16 +337,15 @@ out: | |||
337 | /* | 337 | /* |
338 | * Get ref for the oldest snapc for an inode with dirty data... that is, the | 338 | * Get ref for the oldest snapc for an inode with dirty data... that is, the |
339 | * only snap context we are allowed to write back. | 339 | * only snap context we are allowed to write back. |
340 | * | ||
341 | * Caller holds i_lock. | ||
342 | */ | 340 | */ |
343 | static struct ceph_snap_context *__get_oldest_context(struct inode *inode, | 341 | static struct ceph_snap_context *get_oldest_context(struct inode *inode, |
344 | u64 *snap_size) | 342 | u64 *snap_size) |
345 | { | 343 | { |
346 | struct ceph_inode_info *ci = ceph_inode(inode); | 344 | struct ceph_inode_info *ci = ceph_inode(inode); |
347 | struct ceph_snap_context *snapc = NULL; | 345 | struct ceph_snap_context *snapc = NULL; |
348 | struct ceph_cap_snap *capsnap = NULL; | 346 | struct ceph_cap_snap *capsnap = NULL; |
349 | 347 | ||
348 | spin_lock(&inode->i_lock); | ||
350 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { | 349 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { |
351 | dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, | 350 | dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, |
352 | capsnap->context, capsnap->dirty_pages); | 351 | capsnap->context, capsnap->dirty_pages); |
@@ -357,21 +356,11 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode, | |||
357 | break; | 356 | break; |
358 | } | 357 | } |
359 | } | 358 | } |
360 | if (!snapc && ci->i_snap_realm) { | 359 | if (!snapc && ci->i_head_snapc) { |
361 | snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); | 360 | snapc = ceph_get_snap_context(ci->i_head_snapc); |
362 | dout(" head snapc %p has %d dirty pages\n", | 361 | dout(" head snapc %p has %d dirty pages\n", |
363 | snapc, ci->i_wrbuffer_ref_head); | 362 | snapc, ci->i_wrbuffer_ref_head); |
364 | } | 363 | } |
365 | return snapc; | ||
366 | } | ||
367 | |||
368 | static struct ceph_snap_context *get_oldest_context(struct inode *inode, | ||
369 | u64 *snap_size) | ||
370 | { | ||
371 | struct ceph_snap_context *snapc = NULL; | ||
372 | |||
373 | spin_lock(&inode->i_lock); | ||
374 | snapc = __get_oldest_context(inode, snap_size); | ||
375 | spin_unlock(&inode->i_lock); | 364 | spin_unlock(&inode->i_lock); |
376 | return snapc; | 365 | return snapc; |
377 | } | 366 | } |
@@ -392,7 +381,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
392 | int len = PAGE_CACHE_SIZE; | 381 | int len = PAGE_CACHE_SIZE; |
393 | loff_t i_size; | 382 | loff_t i_size; |
394 | int err = 0; | 383 | int err = 0; |
395 | struct ceph_snap_context *snapc; | 384 | struct ceph_snap_context *snapc, *oldest; |
396 | u64 snap_size = 0; | 385 | u64 snap_size = 0; |
397 | long writeback_stat; | 386 | long writeback_stat; |
398 | 387 | ||
@@ -413,13 +402,16 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
413 | dout("writepage %p page %p not dirty?\n", inode, page); | 402 | dout("writepage %p page %p not dirty?\n", inode, page); |
414 | goto out; | 403 | goto out; |
415 | } | 404 | } |
416 | if (snapc != get_oldest_context(inode, &snap_size)) { | 405 | oldest = get_oldest_context(inode, &snap_size); |
406 | if (snapc->seq > oldest->seq) { | ||
417 | dout("writepage %p page %p snapc %p not writeable - noop\n", | 407 | dout("writepage %p page %p snapc %p not writeable - noop\n", |
418 | inode, page, (void *)page->private); | 408 | inode, page, (void *)page->private); |
419 | /* we should only noop if called by kswapd */ | 409 | /* we should only noop if called by kswapd */ |
420 | WARN_ON((current->flags & PF_MEMALLOC) == 0); | 410 | WARN_ON((current->flags & PF_MEMALLOC) == 0); |
411 | ceph_put_snap_context(oldest); | ||
421 | goto out; | 412 | goto out; |
422 | } | 413 | } |
414 | ceph_put_snap_context(oldest); | ||
423 | 415 | ||
424 | /* is this a partial page at end of file? */ | 416 | /* is this a partial page at end of file? */ |
425 | if (snap_size) | 417 | if (snap_size) |
@@ -458,7 +450,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
458 | ClearPagePrivate(page); | 450 | ClearPagePrivate(page); |
459 | end_page_writeback(page); | 451 | end_page_writeback(page); |
460 | ceph_put_wrbuffer_cap_refs(ci, 1, snapc); | 452 | ceph_put_wrbuffer_cap_refs(ci, 1, snapc); |
461 | ceph_put_snap_context(snapc); | 453 | ceph_put_snap_context(snapc); /* page's reference */ |
462 | out: | 454 | out: |
463 | return err; | 455 | return err; |
464 | } | 456 | } |
@@ -558,9 +550,9 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
558 | dout("inode %p skipping page %p\n", inode, page); | 550 | dout("inode %p skipping page %p\n", inode, page); |
559 | wbc->pages_skipped++; | 551 | wbc->pages_skipped++; |
560 | } | 552 | } |
553 | ceph_put_snap_context((void *)page->private); | ||
561 | page->private = 0; | 554 | page->private = 0; |
562 | ClearPagePrivate(page); | 555 | ClearPagePrivate(page); |
563 | ceph_put_snap_context(snapc); | ||
564 | dout("unlocking %d %p\n", i, page); | 556 | dout("unlocking %d %p\n", i, page); |
565 | end_page_writeback(page); | 557 | end_page_writeback(page); |
566 | 558 | ||
@@ -618,7 +610,7 @@ static int ceph_writepages_start(struct address_space *mapping, | |||
618 | int range_whole = 0; | 610 | int range_whole = 0; |
619 | int should_loop = 1; | 611 | int should_loop = 1; |
620 | pgoff_t max_pages = 0, max_pages_ever = 0; | 612 | pgoff_t max_pages = 0, max_pages_ever = 0; |
621 | struct ceph_snap_context *snapc = NULL, *last_snapc = NULL; | 613 | struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc; |
622 | struct pagevec pvec; | 614 | struct pagevec pvec; |
623 | int done = 0; | 615 | int done = 0; |
624 | int rc = 0; | 616 | int rc = 0; |
@@ -770,9 +762,10 @@ get_more_pages: | |||
770 | } | 762 | } |
771 | 763 | ||
772 | /* only if matching snap context */ | 764 | /* only if matching snap context */ |
773 | if (snapc != (void *)page->private) { | 765 | pgsnapc = (void *)page->private; |
774 | dout("page snapc %p != oldest %p\n", | 766 | if (pgsnapc->seq > snapc->seq) { |
775 | (void *)page->private, snapc); | 767 | dout("page snapc %p %lld > oldest %p %lld\n", |
768 | pgsnapc, pgsnapc->seq, snapc, snapc->seq); | ||
776 | unlock_page(page); | 769 | unlock_page(page); |
777 | if (!locked_pages) | 770 | if (!locked_pages) |
778 | continue; /* keep looking for snap */ | 771 | continue; /* keep looking for snap */ |
@@ -914,7 +907,10 @@ static int context_is_writeable_or_written(struct inode *inode, | |||
914 | struct ceph_snap_context *snapc) | 907 | struct ceph_snap_context *snapc) |
915 | { | 908 | { |
916 | struct ceph_snap_context *oldest = get_oldest_context(inode, NULL); | 909 | struct ceph_snap_context *oldest = get_oldest_context(inode, NULL); |
917 | return !oldest || snapc->seq <= oldest->seq; | 910 | int ret = !oldest || snapc->seq <= oldest->seq; |
911 | |||
912 | ceph_put_snap_context(oldest); | ||
913 | return ret; | ||
918 | } | 914 | } |
919 | 915 | ||
920 | /* | 916 | /* |
@@ -936,8 +932,8 @@ static int ceph_update_writeable_page(struct file *file, | |||
936 | int pos_in_page = pos & ~PAGE_CACHE_MASK; | 932 | int pos_in_page = pos & ~PAGE_CACHE_MASK; |
937 | int end_in_page = pos_in_page + len; | 933 | int end_in_page = pos_in_page + len; |
938 | loff_t i_size; | 934 | loff_t i_size; |
939 | struct ceph_snap_context *snapc; | ||
940 | int r; | 935 | int r; |
936 | struct ceph_snap_context *snapc, *oldest; | ||
941 | 937 | ||
942 | retry_locked: | 938 | retry_locked: |
943 | /* writepages currently holds page lock, but if we change that later, */ | 939 | /* writepages currently holds page lock, but if we change that later, */ |
@@ -947,23 +943,24 @@ retry_locked: | |||
947 | BUG_ON(!ci->i_snap_realm); | 943 | BUG_ON(!ci->i_snap_realm); |
948 | down_read(&mdsc->snap_rwsem); | 944 | down_read(&mdsc->snap_rwsem); |
949 | BUG_ON(!ci->i_snap_realm->cached_context); | 945 | BUG_ON(!ci->i_snap_realm->cached_context); |
950 | if (page->private && | 946 | snapc = (void *)page->private; |
951 | (void *)page->private != ci->i_snap_realm->cached_context) { | 947 | if (snapc && snapc != ci->i_head_snapc) { |
952 | /* | 948 | /* |
953 | * this page is already dirty in another (older) snap | 949 | * this page is already dirty in another (older) snap |
954 | * context! is it writeable now? | 950 | * context! is it writeable now? |
955 | */ | 951 | */ |
956 | snapc = get_oldest_context(inode, NULL); | 952 | oldest = get_oldest_context(inode, NULL); |
957 | up_read(&mdsc->snap_rwsem); | 953 | up_read(&mdsc->snap_rwsem); |
958 | 954 | ||
959 | if (snapc != (void *)page->private) { | 955 | if (snapc->seq > oldest->seq) { |
956 | ceph_put_snap_context(oldest); | ||
960 | dout(" page %p snapc %p not current or oldest\n", | 957 | dout(" page %p snapc %p not current or oldest\n", |
961 | page, (void *)page->private); | 958 | page, snapc); |
962 | /* | 959 | /* |
963 | * queue for writeback, and wait for snapc to | 960 | * queue for writeback, and wait for snapc to |
964 | * be writeable or written | 961 | * be writeable or written |
965 | */ | 962 | */ |
966 | snapc = ceph_get_snap_context((void *)page->private); | 963 | snapc = ceph_get_snap_context(snapc); |
967 | unlock_page(page); | 964 | unlock_page(page); |
968 | ceph_queue_writeback(inode); | 965 | ceph_queue_writeback(inode); |
969 | r = wait_event_interruptible(ci->i_cap_wq, | 966 | r = wait_event_interruptible(ci->i_cap_wq, |
@@ -973,6 +970,7 @@ retry_locked: | |||
973 | return r; | 970 | return r; |
974 | return -EAGAIN; | 971 | return -EAGAIN; |
975 | } | 972 | } |
973 | ceph_put_snap_context(oldest); | ||
976 | 974 | ||
977 | /* yay, writeable, do it now (without dropping page lock) */ | 975 | /* yay, writeable, do it now (without dropping page lock) */ |
978 | dout(" page %p snapc %p not current, but oldest\n", | 976 | dout(" page %p snapc %p not current, but oldest\n", |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 3710e077a857..aa2239fa9a3b 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1205,6 +1205,12 @@ retry: | |||
1205 | if (capsnap->dirty_pages || capsnap->writing) | 1205 | if (capsnap->dirty_pages || capsnap->writing) |
1206 | continue; | 1206 | continue; |
1207 | 1207 | ||
1208 | /* | ||
1209 | * if cap writeback already occurred, we should have dropped | ||
1210 | * the capsnap in ceph_put_wrbuffer_cap_refs. | ||
1211 | */ | ||
1212 | BUG_ON(capsnap->dirty == 0); | ||
1213 | |||
1208 | /* pick mds, take s_mutex */ | 1214 | /* pick mds, take s_mutex */ |
1209 | mds = __ceph_get_cap_mds(ci, &mseq); | 1215 | mds = __ceph_get_cap_mds(ci, &mseq); |
1210 | if (session && session->s_mds != mds) { | 1216 | if (session && session->s_mds != mds) { |
@@ -2118,8 +2124,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) | |||
2118 | } | 2124 | } |
2119 | spin_unlock(&inode->i_lock); | 2125 | spin_unlock(&inode->i_lock); |
2120 | 2126 | ||
2121 | dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had), | 2127 | dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had), |
2122 | last ? "last" : ""); | 2128 | last ? " last" : "", put ? " put" : ""); |
2123 | 2129 | ||
2124 | if (last && !flushsnaps) | 2130 | if (last && !flushsnaps) |
2125 | ceph_check_caps(ci, 0, NULL); | 2131 | ceph_check_caps(ci, 0, NULL); |
@@ -2143,7 +2149,8 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2143 | { | 2149 | { |
2144 | struct inode *inode = &ci->vfs_inode; | 2150 | struct inode *inode = &ci->vfs_inode; |
2145 | int last = 0; | 2151 | int last = 0; |
2146 | int last_snap = 0; | 2152 | int complete_capsnap = 0; |
2153 | int drop_capsnap = 0; | ||
2147 | int found = 0; | 2154 | int found = 0; |
2148 | struct ceph_cap_snap *capsnap = NULL; | 2155 | struct ceph_cap_snap *capsnap = NULL; |
2149 | 2156 | ||
@@ -2166,19 +2173,32 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2166 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { | 2173 | list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { |
2167 | if (capsnap->context == snapc) { | 2174 | if (capsnap->context == snapc) { |
2168 | found = 1; | 2175 | found = 1; |
2169 | capsnap->dirty_pages -= nr; | ||
2170 | last_snap = !capsnap->dirty_pages; | ||
2171 | break; | 2176 | break; |
2172 | } | 2177 | } |
2173 | } | 2178 | } |
2174 | BUG_ON(!found); | 2179 | BUG_ON(!found); |
2180 | capsnap->dirty_pages -= nr; | ||
2181 | if (capsnap->dirty_pages == 0) { | ||
2182 | complete_capsnap = 1; | ||
2183 | if (capsnap->dirty == 0) | ||
2184 | /* cap writeback completed before we created | ||
2185 | * the cap_snap; no FLUSHSNAP is needed */ | ||
2186 | drop_capsnap = 1; | ||
2187 | } | ||
2175 | dout("put_wrbuffer_cap_refs on %p cap_snap %p " | 2188 | dout("put_wrbuffer_cap_refs on %p cap_snap %p " |
2176 | " snap %lld %d/%d -> %d/%d %s%s\n", | 2189 | " snap %lld %d/%d -> %d/%d %s%s%s\n", |
2177 | inode, capsnap, capsnap->context->seq, | 2190 | inode, capsnap, capsnap->context->seq, |
2178 | ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, | 2191 | ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, |
2179 | ci->i_wrbuffer_ref, capsnap->dirty_pages, | 2192 | ci->i_wrbuffer_ref, capsnap->dirty_pages, |
2180 | last ? " (wrbuffer last)" : "", | 2193 | last ? " (wrbuffer last)" : "", |
2181 | last_snap ? " (capsnap last)" : ""); | 2194 | complete_capsnap ? " (complete capsnap)" : "", |
2195 | drop_capsnap ? " (drop capsnap)" : ""); | ||
2196 | if (drop_capsnap) { | ||
2197 | ceph_put_snap_context(capsnap->context); | ||
2198 | list_del(&capsnap->ci_item); | ||
2199 | list_del(&capsnap->flushing_item); | ||
2200 | ceph_put_cap_snap(capsnap); | ||
2201 | } | ||
2182 | } | 2202 | } |
2183 | 2203 | ||
2184 | spin_unlock(&inode->i_lock); | 2204 | spin_unlock(&inode->i_lock); |
@@ -2186,10 +2206,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | |||
2186 | if (last) { | 2206 | if (last) { |
2187 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); | 2207 | ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); |
2188 | iput(inode); | 2208 | iput(inode); |
2189 | } else if (last_snap) { | 2209 | } else if (complete_capsnap) { |
2190 | ceph_flush_snaps(ci); | 2210 | ceph_flush_snaps(ci); |
2191 | wake_up(&ci->i_cap_wq); | 2211 | wake_up(&ci->i_cap_wq); |
2192 | } | 2212 | } |
2213 | if (drop_capsnap) | ||
2214 | iput(inode); | ||
2193 | } | 2215 | } |
2194 | 2216 | ||
2195 | /* | 2217 | /* |
@@ -2465,8 +2487,8 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, | |||
2465 | break; | 2487 | break; |
2466 | } | 2488 | } |
2467 | WARN_ON(capsnap->dirty_pages || capsnap->writing); | 2489 | WARN_ON(capsnap->dirty_pages || capsnap->writing); |
2468 | dout(" removing cap_snap %p follows %lld\n", | 2490 | dout(" removing %p cap_snap %p follows %lld\n", |
2469 | capsnap, follows); | 2491 | inode, capsnap, follows); |
2470 | ceph_put_snap_context(capsnap->context); | 2492 | ceph_put_snap_context(capsnap->context); |
2471 | list_del(&capsnap->ci_item); | 2493 | list_del(&capsnap->ci_item); |
2472 | list_del(&capsnap->flushing_item); | 2494 | list_del(&capsnap->flushing_item); |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7261dc6c2ead..ea8ee2e526aa 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -171,11 +171,11 @@ more: | |||
171 | spin_lock(&inode->i_lock); | 171 | spin_lock(&inode->i_lock); |
172 | spin_lock(&dcache_lock); | 172 | spin_lock(&dcache_lock); |
173 | 173 | ||
174 | last = dentry; | ||
175 | |||
174 | if (err < 0) | 176 | if (err < 0) |
175 | goto out_unlock; | 177 | goto out_unlock; |
176 | 178 | ||
177 | last = dentry; | ||
178 | |||
179 | p = p->prev; | 179 | p = p->prev; |
180 | filp->f_pos++; | 180 | filp->f_pos++; |
181 | 181 | ||
@@ -312,7 +312,7 @@ more: | |||
312 | req->r_readdir_offset = fi->next_offset; | 312 | req->r_readdir_offset = fi->next_offset; |
313 | req->r_args.readdir.frag = cpu_to_le32(frag); | 313 | req->r_args.readdir.frag = cpu_to_le32(frag); |
314 | req->r_args.readdir.max_entries = cpu_to_le32(max_entries); | 314 | req->r_args.readdir.max_entries = cpu_to_le32(max_entries); |
315 | req->r_num_caps = max_entries; | 315 | req->r_num_caps = max_entries + 1; |
316 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 316 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
317 | if (err < 0) { | 317 | if (err < 0) { |
318 | ceph_mdsc_put_request(req); | 318 | ceph_mdsc_put_request(req); |
@@ -489,6 +489,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, | |||
489 | struct inode *inode = ceph_get_snapdir(parent); | 489 | struct inode *inode = ceph_get_snapdir(parent); |
490 | dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", | 490 | dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", |
491 | dentry, dentry->d_name.len, dentry->d_name.name, inode); | 491 | dentry, dentry->d_name.len, dentry->d_name.name, inode); |
492 | BUG_ON(!d_unhashed(dentry)); | ||
492 | d_add(dentry, inode); | 493 | d_add(dentry, inode); |
493 | err = 0; | 494 | err = 0; |
494 | } | 495 | } |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index aca82d55cc53..26f883c275e8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -886,6 +886,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
886 | struct inode *in = NULL; | 886 | struct inode *in = NULL; |
887 | struct ceph_mds_reply_inode *ininfo; | 887 | struct ceph_mds_reply_inode *ininfo; |
888 | struct ceph_vino vino; | 888 | struct ceph_vino vino; |
889 | struct ceph_client *client = ceph_sb_to_client(sb); | ||
889 | int i = 0; | 890 | int i = 0; |
890 | int err = 0; | 891 | int err = 0; |
891 | 892 | ||
@@ -949,7 +950,14 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
949 | return err; | 950 | return err; |
950 | } | 951 | } |
951 | 952 | ||
952 | if (rinfo->head->is_dentry && !req->r_aborted) { | 953 | /* |
954 | * ignore null lease/binding on snapdir ENOENT, or else we | ||
955 | * will have trouble splicing in the virtual snapdir later | ||
956 | */ | ||
957 | if (rinfo->head->is_dentry && !req->r_aborted && | ||
958 | (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, | ||
959 | client->mount_args->snapdir_name, | ||
960 | req->r_dentry->d_name.len))) { | ||
953 | /* | 961 | /* |
954 | * lookup link rename : null -> possibly existing inode | 962 | * lookup link rename : null -> possibly existing inode |
955 | * mknod symlink mkdir : null -> new inode | 963 | * mknod symlink mkdir : null -> new inode |
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 8f1715ffbe4b..cdaaa131add3 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -30,6 +30,10 @@ static char tag_msg = CEPH_MSGR_TAG_MSG; | |||
30 | static char tag_ack = CEPH_MSGR_TAG_ACK; | 30 | static char tag_ack = CEPH_MSGR_TAG_ACK; |
31 | static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; | 31 | static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; |
32 | 32 | ||
33 | #ifdef CONFIG_LOCKDEP | ||
34 | static struct lock_class_key socket_class; | ||
35 | #endif | ||
36 | |||
33 | 37 | ||
34 | static void queue_con(struct ceph_connection *con); | 38 | static void queue_con(struct ceph_connection *con); |
35 | static void con_work(struct work_struct *); | 39 | static void con_work(struct work_struct *); |
@@ -228,6 +232,10 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con) | |||
228 | con->sock = sock; | 232 | con->sock = sock; |
229 | sock->sk->sk_allocation = GFP_NOFS; | 233 | sock->sk->sk_allocation = GFP_NOFS; |
230 | 234 | ||
235 | #ifdef CONFIG_LOCKDEP | ||
236 | lockdep_set_class(&sock->sk->sk_lock, &socket_class); | ||
237 | #endif | ||
238 | |||
231 | set_sock_callbacks(sock, con); | 239 | set_sock_callbacks(sock, con); |
232 | 240 | ||
233 | dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); | 241 | dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); |
@@ -333,6 +341,7 @@ static void reset_connection(struct ceph_connection *con) | |||
333 | con->out_msg = NULL; | 341 | con->out_msg = NULL; |
334 | } | 342 | } |
335 | con->in_seq = 0; | 343 | con->in_seq = 0; |
344 | con->in_seq_acked = 0; | ||
336 | } | 345 | } |
337 | 346 | ||
338 | /* | 347 | /* |
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 21c6623c4b07..2e2c15eed82a 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
@@ -314,71 +314,6 @@ bad: | |||
314 | return ERR_PTR(err); | 314 | return ERR_PTR(err); |
315 | } | 315 | } |
316 | 316 | ||
317 | |||
318 | /* | ||
319 | * osd map | ||
320 | */ | ||
321 | void ceph_osdmap_destroy(struct ceph_osdmap *map) | ||
322 | { | ||
323 | dout("osdmap_destroy %p\n", map); | ||
324 | if (map->crush) | ||
325 | crush_destroy(map->crush); | ||
326 | while (!RB_EMPTY_ROOT(&map->pg_temp)) { | ||
327 | struct ceph_pg_mapping *pg = | ||
328 | rb_entry(rb_first(&map->pg_temp), | ||
329 | struct ceph_pg_mapping, node); | ||
330 | rb_erase(&pg->node, &map->pg_temp); | ||
331 | kfree(pg); | ||
332 | } | ||
333 | while (!RB_EMPTY_ROOT(&map->pg_pools)) { | ||
334 | struct ceph_pg_pool_info *pi = | ||
335 | rb_entry(rb_first(&map->pg_pools), | ||
336 | struct ceph_pg_pool_info, node); | ||
337 | rb_erase(&pi->node, &map->pg_pools); | ||
338 | kfree(pi); | ||
339 | } | ||
340 | kfree(map->osd_state); | ||
341 | kfree(map->osd_weight); | ||
342 | kfree(map->osd_addr); | ||
343 | kfree(map); | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * adjust max osd value. reallocate arrays. | ||
348 | */ | ||
349 | static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | ||
350 | { | ||
351 | u8 *state; | ||
352 | struct ceph_entity_addr *addr; | ||
353 | u32 *weight; | ||
354 | |||
355 | state = kcalloc(max, sizeof(*state), GFP_NOFS); | ||
356 | addr = kcalloc(max, sizeof(*addr), GFP_NOFS); | ||
357 | weight = kcalloc(max, sizeof(*weight), GFP_NOFS); | ||
358 | if (state == NULL || addr == NULL || weight == NULL) { | ||
359 | kfree(state); | ||
360 | kfree(addr); | ||
361 | kfree(weight); | ||
362 | return -ENOMEM; | ||
363 | } | ||
364 | |||
365 | /* copy old? */ | ||
366 | if (map->osd_state) { | ||
367 | memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); | ||
368 | memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); | ||
369 | memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); | ||
370 | kfree(map->osd_state); | ||
371 | kfree(map->osd_addr); | ||
372 | kfree(map->osd_weight); | ||
373 | } | ||
374 | |||
375 | map->osd_state = state; | ||
376 | map->osd_weight = weight; | ||
377 | map->osd_addr = addr; | ||
378 | map->max_osd = max; | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* | 317 | /* |
383 | * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid | 318 | * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid |
384 | * to a set of osds) | 319 | * to a set of osds) |
@@ -482,6 +417,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) | |||
482 | return NULL; | 417 | return NULL; |
483 | } | 418 | } |
484 | 419 | ||
420 | static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) | ||
421 | { | ||
422 | rb_erase(&pi->node, root); | ||
423 | kfree(pi->name); | ||
424 | kfree(pi); | ||
425 | } | ||
426 | |||
485 | void __decode_pool(void **p, struct ceph_pg_pool_info *pi) | 427 | void __decode_pool(void **p, struct ceph_pg_pool_info *pi) |
486 | { | 428 | { |
487 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); | 429 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); |
@@ -490,6 +432,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi) | |||
490 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; | 432 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; |
491 | } | 433 | } |
492 | 434 | ||
435 | static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) | ||
436 | { | ||
437 | struct ceph_pg_pool_info *pi; | ||
438 | u32 num, len, pool; | ||
439 | |||
440 | ceph_decode_32_safe(p, end, num, bad); | ||
441 | dout(" %d pool names\n", num); | ||
442 | while (num--) { | ||
443 | ceph_decode_32_safe(p, end, pool, bad); | ||
444 | ceph_decode_32_safe(p, end, len, bad); | ||
445 | dout(" pool %d len %d\n", pool, len); | ||
446 | pi = __lookup_pg_pool(&map->pg_pools, pool); | ||
447 | if (pi) { | ||
448 | kfree(pi->name); | ||
449 | pi->name = kmalloc(len + 1, GFP_NOFS); | ||
450 | if (pi->name) { | ||
451 | memcpy(pi->name, *p, len); | ||
452 | pi->name[len] = '\0'; | ||
453 | dout(" name is %s\n", pi->name); | ||
454 | } | ||
455 | } | ||
456 | *p += len; | ||
457 | } | ||
458 | return 0; | ||
459 | |||
460 | bad: | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * osd map | ||
466 | */ | ||
467 | void ceph_osdmap_destroy(struct ceph_osdmap *map) | ||
468 | { | ||
469 | dout("osdmap_destroy %p\n", map); | ||
470 | if (map->crush) | ||
471 | crush_destroy(map->crush); | ||
472 | while (!RB_EMPTY_ROOT(&map->pg_temp)) { | ||
473 | struct ceph_pg_mapping *pg = | ||
474 | rb_entry(rb_first(&map->pg_temp), | ||
475 | struct ceph_pg_mapping, node); | ||
476 | rb_erase(&pg->node, &map->pg_temp); | ||
477 | kfree(pg); | ||
478 | } | ||
479 | while (!RB_EMPTY_ROOT(&map->pg_pools)) { | ||
480 | struct ceph_pg_pool_info *pi = | ||
481 | rb_entry(rb_first(&map->pg_pools), | ||
482 | struct ceph_pg_pool_info, node); | ||
483 | __remove_pg_pool(&map->pg_pools, pi); | ||
484 | } | ||
485 | kfree(map->osd_state); | ||
486 | kfree(map->osd_weight); | ||
487 | kfree(map->osd_addr); | ||
488 | kfree(map); | ||
489 | } | ||
490 | |||
491 | /* | ||
492 | * adjust max osd value. reallocate arrays. | ||
493 | */ | ||
494 | static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | ||
495 | { | ||
496 | u8 *state; | ||
497 | struct ceph_entity_addr *addr; | ||
498 | u32 *weight; | ||
499 | |||
500 | state = kcalloc(max, sizeof(*state), GFP_NOFS); | ||
501 | addr = kcalloc(max, sizeof(*addr), GFP_NOFS); | ||
502 | weight = kcalloc(max, sizeof(*weight), GFP_NOFS); | ||
503 | if (state == NULL || addr == NULL || weight == NULL) { | ||
504 | kfree(state); | ||
505 | kfree(addr); | ||
506 | kfree(weight); | ||
507 | return -ENOMEM; | ||
508 | } | ||
509 | |||
510 | /* copy old? */ | ||
511 | if (map->osd_state) { | ||
512 | memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); | ||
513 | memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); | ||
514 | memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); | ||
515 | kfree(map->osd_state); | ||
516 | kfree(map->osd_addr); | ||
517 | kfree(map->osd_weight); | ||
518 | } | ||
519 | |||
520 | map->osd_state = state; | ||
521 | map->osd_weight = weight; | ||
522 | map->osd_addr = addr; | ||
523 | map->max_osd = max; | ||
524 | return 0; | ||
525 | } | ||
526 | |||
493 | /* | 527 | /* |
494 | * decode a full map. | 528 | * decode a full map. |
495 | */ | 529 | */ |
@@ -526,7 +560,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
526 | ceph_decode_32_safe(p, end, max, bad); | 560 | ceph_decode_32_safe(p, end, max, bad); |
527 | while (max--) { | 561 | while (max--) { |
528 | ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); | 562 | ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); |
529 | pi = kmalloc(sizeof(*pi), GFP_NOFS); | 563 | pi = kzalloc(sizeof(*pi), GFP_NOFS); |
530 | if (!pi) | 564 | if (!pi) |
531 | goto bad; | 565 | goto bad; |
532 | pi->id = ceph_decode_32(p); | 566 | pi->id = ceph_decode_32(p); |
@@ -539,6 +573,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
539 | __decode_pool(p, pi); | 573 | __decode_pool(p, pi); |
540 | __insert_pg_pool(&map->pg_pools, pi); | 574 | __insert_pg_pool(&map->pg_pools, pi); |
541 | } | 575 | } |
576 | |||
577 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) | ||
578 | goto bad; | ||
579 | |||
542 | ceph_decode_32_safe(p, end, map->pool_max, bad); | 580 | ceph_decode_32_safe(p, end, map->pool_max, bad); |
543 | 581 | ||
544 | ceph_decode_32_safe(p, end, map->flags, bad); | 582 | ceph_decode_32_safe(p, end, map->flags, bad); |
@@ -712,7 +750,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
712 | } | 750 | } |
713 | pi = __lookup_pg_pool(&map->pg_pools, pool); | 751 | pi = __lookup_pg_pool(&map->pg_pools, pool); |
714 | if (!pi) { | 752 | if (!pi) { |
715 | pi = kmalloc(sizeof(*pi), GFP_NOFS); | 753 | pi = kzalloc(sizeof(*pi), GFP_NOFS); |
716 | if (!pi) { | 754 | if (!pi) { |
717 | err = -ENOMEM; | 755 | err = -ENOMEM; |
718 | goto bad; | 756 | goto bad; |
@@ -722,6 +760,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
722 | } | 760 | } |
723 | __decode_pool(p, pi); | 761 | __decode_pool(p, pi); |
724 | } | 762 | } |
763 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) | ||
764 | goto bad; | ||
725 | 765 | ||
726 | /* old_pool */ | 766 | /* old_pool */ |
727 | ceph_decode_32_safe(p, end, len, bad); | 767 | ceph_decode_32_safe(p, end, len, bad); |
@@ -730,10 +770,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
730 | 770 | ||
731 | ceph_decode_32_safe(p, end, pool, bad); | 771 | ceph_decode_32_safe(p, end, pool, bad); |
732 | pi = __lookup_pg_pool(&map->pg_pools, pool); | 772 | pi = __lookup_pg_pool(&map->pg_pools, pool); |
733 | if (pi) { | 773 | if (pi) |
734 | rb_erase(&pi->node, &map->pg_pools); | 774 | __remove_pg_pool(&map->pg_pools, pi); |
735 | kfree(pi); | ||
736 | } | ||
737 | } | 775 | } |
738 | 776 | ||
739 | /* new_up */ | 777 | /* new_up */ |
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 1fb55afb2642..8bc9f1e4f562 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h | |||
@@ -23,6 +23,7 @@ struct ceph_pg_pool_info { | |||
23 | int id; | 23 | int id; |
24 | struct ceph_pg_pool v; | 24 | struct ceph_pg_pool v; |
25 | int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; | 25 | int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; |
26 | char *name; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct ceph_pg_mapping { | 29 | struct ceph_pg_mapping { |
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 26ac8b89a676..a1fc1d017b58 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h | |||
@@ -11,8 +11,10 @@ | |||
11 | /* | 11 | /* |
12 | * osdmap encoding versions | 12 | * osdmap encoding versions |
13 | */ | 13 | */ |
14 | #define CEPH_OSDMAP_INC_VERSION 4 | 14 | #define CEPH_OSDMAP_INC_VERSION 5 |
15 | #define CEPH_OSDMAP_VERSION 4 | 15 | #define CEPH_OSDMAP_INC_VERSION_EXT 5 |
16 | #define CEPH_OSDMAP_VERSION 5 | ||
17 | #define CEPH_OSDMAP_VERSION_EXT 5 | ||
16 | 18 | ||
17 | /* | 19 | /* |
18 | * fs id | 20 | * fs id |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index e6f9bc57d472..2b881262ef67 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -431,8 +431,7 @@ static int dup_array(u64 **dst, __le64 *src, int num) | |||
431 | * Caller must hold snap_rwsem for read (i.e., the realm topology won't | 431 | * Caller must hold snap_rwsem for read (i.e., the realm topology won't |
432 | * change). | 432 | * change). |
433 | */ | 433 | */ |
434 | void ceph_queue_cap_snap(struct ceph_inode_info *ci, | 434 | void ceph_queue_cap_snap(struct ceph_inode_info *ci) |
435 | struct ceph_snap_context *snapc) | ||
436 | { | 435 | { |
437 | struct inode *inode = &ci->vfs_inode; | 436 | struct inode *inode = &ci->vfs_inode; |
438 | struct ceph_cap_snap *capsnap; | 437 | struct ceph_cap_snap *capsnap; |
@@ -451,10 +450,11 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, | |||
451 | as no new writes are allowed to start when pending, so any | 450 | as no new writes are allowed to start when pending, so any |
452 | writes in progress now were started before the previous | 451 | writes in progress now were started before the previous |
453 | cap_snap. lucky us. */ | 452 | cap_snap. lucky us. */ |
454 | dout("queue_cap_snap %p snapc %p seq %llu used %d" | 453 | dout("queue_cap_snap %p already pending\n", inode); |
455 | " already pending\n", inode, snapc, snapc->seq, used); | ||
456 | kfree(capsnap); | 454 | kfree(capsnap); |
457 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { | 455 | } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { |
456 | struct ceph_snap_context *snapc = ci->i_head_snapc; | ||
457 | |||
458 | igrab(inode); | 458 | igrab(inode); |
459 | 459 | ||
460 | atomic_set(&capsnap->nref, 1); | 460 | atomic_set(&capsnap->nref, 1); |
@@ -463,7 +463,6 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, | |||
463 | INIT_LIST_HEAD(&capsnap->flushing_item); | 463 | INIT_LIST_HEAD(&capsnap->flushing_item); |
464 | 464 | ||
465 | capsnap->follows = snapc->seq - 1; | 465 | capsnap->follows = snapc->seq - 1; |
466 | capsnap->context = ceph_get_snap_context(snapc); | ||
467 | capsnap->issued = __ceph_caps_issued(ci, NULL); | 466 | capsnap->issued = __ceph_caps_issued(ci, NULL); |
468 | capsnap->dirty = __ceph_caps_dirty(ci); | 467 | capsnap->dirty = __ceph_caps_dirty(ci); |
469 | 468 | ||
@@ -480,7 +479,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci, | |||
480 | snapshot. */ | 479 | snapshot. */ |
481 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; | 480 | capsnap->dirty_pages = ci->i_wrbuffer_ref_head; |
482 | ci->i_wrbuffer_ref_head = 0; | 481 | ci->i_wrbuffer_ref_head = 0; |
483 | ceph_put_snap_context(ci->i_head_snapc); | 482 | capsnap->context = snapc; |
484 | ci->i_head_snapc = NULL; | 483 | ci->i_head_snapc = NULL; |
485 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); | 484 | list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); |
486 | 485 | ||
@@ -522,15 +521,17 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci, | |||
522 | capsnap->ctime = inode->i_ctime; | 521 | capsnap->ctime = inode->i_ctime; |
523 | capsnap->time_warp_seq = ci->i_time_warp_seq; | 522 | capsnap->time_warp_seq = ci->i_time_warp_seq; |
524 | if (capsnap->dirty_pages) { | 523 | if (capsnap->dirty_pages) { |
525 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu " | 524 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu " |
526 | "still has %d dirty pages\n", inode, capsnap, | 525 | "still has %d dirty pages\n", inode, capsnap, |
527 | capsnap->context, capsnap->context->seq, | 526 | capsnap->context, capsnap->context->seq, |
528 | capsnap->size, capsnap->dirty_pages); | 527 | ceph_cap_string(capsnap->dirty), capsnap->size, |
528 | capsnap->dirty_pages); | ||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n", | 531 | dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n", |
532 | inode, capsnap, capsnap->context, | 532 | inode, capsnap, capsnap->context, |
533 | capsnap->context->seq, capsnap->size); | 533 | capsnap->context->seq, ceph_cap_string(capsnap->dirty), |
534 | capsnap->size); | ||
534 | 535 | ||
535 | spin_lock(&mdsc->snap_flush_lock); | 536 | spin_lock(&mdsc->snap_flush_lock); |
536 | list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); | 537 | list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); |
@@ -602,7 +603,7 @@ more: | |||
602 | if (lastinode) | 603 | if (lastinode) |
603 | iput(lastinode); | 604 | iput(lastinode); |
604 | lastinode = inode; | 605 | lastinode = inode; |
605 | ceph_queue_cap_snap(ci, realm->cached_context); | 606 | ceph_queue_cap_snap(ci); |
606 | spin_lock(&realm->inodes_with_caps_lock); | 607 | spin_lock(&realm->inodes_with_caps_lock); |
607 | } | 608 | } |
608 | spin_unlock(&realm->inodes_with_caps_lock); | 609 | spin_unlock(&realm->inodes_with_caps_lock); |
@@ -824,8 +825,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, | |||
824 | spin_unlock(&realm->inodes_with_caps_lock); | 825 | spin_unlock(&realm->inodes_with_caps_lock); |
825 | spin_unlock(&inode->i_lock); | 826 | spin_unlock(&inode->i_lock); |
826 | 827 | ||
827 | ceph_queue_cap_snap(ci, | 828 | ceph_queue_cap_snap(ci); |
828 | ci->i_snap_realm->cached_context); | ||
829 | 829 | ||
830 | iput(inode); | 830 | iput(inode); |
831 | continue; | 831 | continue; |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index ca702c67bc66..e30dfbb056c3 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -715,8 +715,7 @@ extern int ceph_update_snap_trace(struct ceph_mds_client *m, | |||
715 | extern void ceph_handle_snap(struct ceph_mds_client *mdsc, | 715 | extern void ceph_handle_snap(struct ceph_mds_client *mdsc, |
716 | struct ceph_mds_session *session, | 716 | struct ceph_mds_session *session, |
717 | struct ceph_msg *msg); | 717 | struct ceph_msg *msg); |
718 | extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, | 718 | extern void ceph_queue_cap_snap(struct ceph_inode_info *ci); |
719 | struct ceph_snap_context *snapc); | ||
720 | extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, | 719 | extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, |
721 | struct ceph_cap_snap *capsnap); | 720 | struct ceph_cap_snap *capsnap); |
722 | extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); | 721 | extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5183bc2a1916..ded66be6597c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -808,6 +808,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { | |||
808 | .release = cifs_close, | 808 | .release = cifs_close, |
809 | .fsync = cifs_fsync, | 809 | .fsync = cifs_fsync, |
810 | .flush = cifs_flush, | 810 | .flush = cifs_flush, |
811 | .mmap = cifs_file_mmap, | ||
811 | .splice_read = generic_file_splice_read, | 812 | .splice_read = generic_file_splice_read, |
812 | #ifdef CONFIG_CIFS_POSIX | 813 | #ifdef CONFIG_CIFS_POSIX |
813 | .unlocked_ioctl = cifs_ioctl, | 814 | .unlocked_ioctl = cifs_ioctl, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3f4fbd670507..5d3f29fef532 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1431,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
1431 | __u32 bytes_sent; | 1431 | __u32 bytes_sent; |
1432 | __u16 byte_count; | 1432 | __u16 byte_count; |
1433 | 1433 | ||
1434 | *nbytes = 0; | ||
1435 | |||
1434 | /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ | 1436 | /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ |
1435 | if (tcon->ses == NULL) | 1437 | if (tcon->ses == NULL) |
1436 | return -ECONNABORTED; | 1438 | return -ECONNABORTED; |
@@ -1513,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
1513 | cifs_stats_inc(&tcon->num_writes); | 1515 | cifs_stats_inc(&tcon->num_writes); |
1514 | if (rc) { | 1516 | if (rc) { |
1515 | cFYI(1, ("Send error in write = %d", rc)); | 1517 | cFYI(1, ("Send error in write = %d", rc)); |
1516 | *nbytes = 0; | ||
1517 | } else { | 1518 | } else { |
1518 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1519 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
1519 | *nbytes = (*nbytes) << 16; | 1520 | *nbytes = (*nbytes) << 16; |
1520 | *nbytes += le16_to_cpu(pSMBr->Count); | 1521 | *nbytes += le16_to_cpu(pSMBr->Count); |
1522 | |||
1523 | /* | ||
1524 | * Mask off high 16 bits when bytes written as returned by the | ||
1525 | * server is greater than bytes requested by the client. Some | ||
1526 | * OS/2 servers are known to set incorrect CountHigh values. | ||
1527 | */ | ||
1528 | if (*nbytes > count) | ||
1529 | *nbytes &= 0xFFFF; | ||
1521 | } | 1530 | } |
1522 | 1531 | ||
1523 | cifs_buf_release(pSMB); | 1532 | cifs_buf_release(pSMB); |
@@ -1606,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
1606 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1615 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
1607 | *nbytes = (*nbytes) << 16; | 1616 | *nbytes = (*nbytes) << 16; |
1608 | *nbytes += le16_to_cpu(pSMBr->Count); | 1617 | *nbytes += le16_to_cpu(pSMBr->Count); |
1618 | |||
1619 | /* | ||
1620 | * Mask off high 16 bits when bytes written as returned by the | ||
1621 | * server is greater than bytes requested by the client. OS/2 | ||
1622 | * servers are known to set incorrect CountHigh values. | ||
1623 | */ | ||
1624 | if (*nbytes > count) | ||
1625 | *nbytes &= 0xFFFF; | ||
1609 | } | 1626 | } |
1610 | 1627 | ||
1611 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 1628 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
@@ -1794,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
1794 | } | 1811 | } |
1795 | parm_data = (struct cifs_posix_lock *) | 1812 | parm_data = (struct cifs_posix_lock *) |
1796 | ((char *)&pSMBr->hdr.Protocol + data_offset); | 1813 | ((char *)&pSMBr->hdr.Protocol + data_offset); |
1797 | if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) | 1814 | if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK)) |
1798 | pLockData->fl_type = F_UNLCK; | 1815 | pLockData->fl_type = F_UNLCK; |
1816 | else { | ||
1817 | if (parm_data->lock_type == | ||
1818 | __constant_cpu_to_le16(CIFS_RDLCK)) | ||
1819 | pLockData->fl_type = F_RDLCK; | ||
1820 | else if (parm_data->lock_type == | ||
1821 | __constant_cpu_to_le16(CIFS_WRLCK)) | ||
1822 | pLockData->fl_type = F_WRLCK; | ||
1823 | |||
1824 | pLockData->fl_start = parm_data->start; | ||
1825 | pLockData->fl_end = parm_data->start + | ||
1826 | parm_data->length - 1; | ||
1827 | pLockData->fl_pid = parm_data->pid; | ||
1828 | } | ||
1799 | } | 1829 | } |
1800 | 1830 | ||
1801 | plk_err_exit: | 1831 | plk_err_exit: |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 058b390d3da8..9b11a8f56f3a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -839,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
839 | 839 | ||
840 | } else { | 840 | } else { |
841 | /* if rc == ERR_SHARING_VIOLATION ? */ | 841 | /* if rc == ERR_SHARING_VIOLATION ? */ |
842 | rc = 0; /* do not change lock type to unlock | 842 | rc = 0; |
843 | since range in use */ | 843 | |
844 | if (lockType & LOCKING_ANDX_SHARED_LOCK) { | ||
845 | pfLock->fl_type = F_WRLCK; | ||
846 | } else { | ||
847 | rc = CIFSSMBLock(xid, tcon, netfid, length, | ||
848 | pfLock->fl_start, 0, 1, | ||
849 | lockType | LOCKING_ANDX_SHARED_LOCK, | ||
850 | 0 /* wait flag */); | ||
851 | if (rc == 0) { | ||
852 | rc = CIFSSMBLock(xid, tcon, netfid, | ||
853 | length, pfLock->fl_start, 1, 0, | ||
854 | lockType | | ||
855 | LOCKING_ANDX_SHARED_LOCK, | ||
856 | 0 /* wait flag */); | ||
857 | pfLock->fl_type = F_RDLCK; | ||
858 | if (rc != 0) | ||
859 | cERROR(1, ("Error unlocking " | ||
860 | "previously locked range %d " | ||
861 | "during test of lock", rc)); | ||
862 | rc = 0; | ||
863 | } else { | ||
864 | pfLock->fl_type = F_WRLCK; | ||
865 | rc = 0; | ||
866 | } | ||
867 | } | ||
844 | } | 868 | } |
845 | 869 | ||
846 | FreeXid(xid); | 870 | FreeXid(xid); |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index efb2b9400391..1cc087635a5e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -382,8 +382,8 @@ out: | |||
382 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, | 382 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, |
383 | struct ecryptfs_crypt_stat *crypt_stat) | 383 | struct ecryptfs_crypt_stat *crypt_stat) |
384 | { | 384 | { |
385 | (*offset) = (crypt_stat->num_header_bytes_at_front | 385 | (*offset) = ecryptfs_lower_header_size(crypt_stat) |
386 | + (crypt_stat->extent_size * extent_num)); | 386 | + (crypt_stat->extent_size * extent_num); |
387 | } | 387 | } |
388 | 388 | ||
389 | /** | 389 | /** |
@@ -835,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | |||
835 | set_extent_mask_and_shift(crypt_stat); | 835 | set_extent_mask_and_shift(crypt_stat); |
836 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; | 836 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; |
837 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 837 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
838 | crypt_stat->num_header_bytes_at_front = 0; | 838 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
839 | else { | 839 | else { |
840 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) | 840 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) |
841 | crypt_stat->num_header_bytes_at_front = | 841 | crypt_stat->metadata_size = |
842 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | 842 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
843 | else | 843 | else |
844 | crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; | 844 | crypt_stat->metadata_size = PAGE_CACHE_SIZE; |
845 | } | 845 | } |
846 | } | 846 | } |
847 | 847 | ||
@@ -1108,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written) | |||
1108 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; | 1108 | (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | static void | 1111 | void ecryptfs_write_crypt_stat_flags(char *page_virt, |
1112 | write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | 1112 | struct ecryptfs_crypt_stat *crypt_stat, |
1113 | size_t *written) | 1113 | size_t *written) |
1114 | { | 1114 | { |
1115 | u32 flags = 0; | 1115 | u32 flags = 0; |
1116 | int i; | 1116 | int i; |
@@ -1238,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
1238 | 1238 | ||
1239 | header_extent_size = (u32)crypt_stat->extent_size; | 1239 | header_extent_size = (u32)crypt_stat->extent_size; |
1240 | num_header_extents_at_front = | 1240 | num_header_extents_at_front = |
1241 | (u16)(crypt_stat->num_header_bytes_at_front | 1241 | (u16)(crypt_stat->metadata_size / crypt_stat->extent_size); |
1242 | / crypt_stat->extent_size); | ||
1243 | put_unaligned_be32(header_extent_size, virt); | 1242 | put_unaligned_be32(header_extent_size, virt); |
1244 | virt += 4; | 1243 | virt += 4; |
1245 | put_unaligned_be16(num_header_extents_at_front, virt); | 1244 | put_unaligned_be16(num_header_extents_at_front, virt); |
@@ -1292,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, | |||
1292 | offset = ECRYPTFS_FILE_SIZE_BYTES; | 1291 | offset = ECRYPTFS_FILE_SIZE_BYTES; |
1293 | write_ecryptfs_marker((page_virt + offset), &written); | 1292 | write_ecryptfs_marker((page_virt + offset), &written); |
1294 | offset += written; | 1293 | offset += written; |
1295 | write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); | 1294 | ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat, |
1295 | &written); | ||
1296 | offset += written; | 1296 | offset += written; |
1297 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, | 1297 | ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, |
1298 | &written); | 1298 | &written); |
@@ -1382,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1382 | rc = -EINVAL; | 1382 | rc = -EINVAL; |
1383 | goto out; | 1383 | goto out; |
1384 | } | 1384 | } |
1385 | virt_len = crypt_stat->num_header_bytes_at_front; | 1385 | virt_len = crypt_stat->metadata_size; |
1386 | order = get_order(virt_len); | 1386 | order = get_order(virt_len); |
1387 | /* Released in this function */ | 1387 | /* Released in this function */ |
1388 | virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); | 1388 | virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); |
@@ -1428,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1428 | header_extent_size = get_unaligned_be32(virt); | 1428 | header_extent_size = get_unaligned_be32(virt); |
1429 | virt += sizeof(__be32); | 1429 | virt += sizeof(__be32); |
1430 | num_header_extents_at_front = get_unaligned_be16(virt); | 1430 | num_header_extents_at_front = get_unaligned_be16(virt); |
1431 | crypt_stat->num_header_bytes_at_front = | 1431 | crypt_stat->metadata_size = (((size_t)num_header_extents_at_front |
1432 | (((size_t)num_header_extents_at_front | 1432 | * (size_t)header_extent_size)); |
1433 | * (size_t)header_extent_size)); | ||
1434 | (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); | 1433 | (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); |
1435 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) | 1434 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1436 | && (crypt_stat->num_header_bytes_at_front | 1435 | && (crypt_stat->metadata_size |
1437 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | 1436 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { |
1438 | rc = -EINVAL; | 1437 | rc = -EINVAL; |
1439 | printk(KERN_WARNING "Invalid header size: [%zd]\n", | 1438 | printk(KERN_WARNING "Invalid header size: [%zd]\n", |
1440 | crypt_stat->num_header_bytes_at_front); | 1439 | crypt_stat->metadata_size); |
1441 | } | 1440 | } |
1442 | return rc; | 1441 | return rc; |
1443 | } | 1442 | } |
@@ -1452,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1452 | */ | 1451 | */ |
1453 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | 1452 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) |
1454 | { | 1453 | { |
1455 | crypt_stat->num_header_bytes_at_front = | 1454 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
1456 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
1457 | } | 1455 | } |
1458 | 1456 | ||
1459 | /** | 1457 | /** |
@@ -1607,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1607 | ecryptfs_dentry, | 1605 | ecryptfs_dentry, |
1608 | ECRYPTFS_VALIDATE_HEADER_SIZE); | 1606 | ECRYPTFS_VALIDATE_HEADER_SIZE); |
1609 | if (rc) { | 1607 | if (rc) { |
1608 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1610 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); | 1609 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); |
1611 | if (rc) { | 1610 | if (rc) { |
1612 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | 1611 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 542f625312f3..bc7115403f38 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat { | |||
273 | u32 flags; | 273 | u32 flags; |
274 | unsigned int file_version; | 274 | unsigned int file_version; |
275 | size_t iv_bytes; | 275 | size_t iv_bytes; |
276 | size_t num_header_bytes_at_front; | 276 | size_t metadata_size; |
277 | size_t extent_size; /* Data extent size; default is 4096 */ | 277 | size_t extent_size; /* Data extent size; default is 4096 */ |
278 | size_t key_size; | 278 | size_t key_size; |
279 | size_t extent_shift; | 279 | size_t extent_shift; |
@@ -464,6 +464,14 @@ struct ecryptfs_daemon { | |||
464 | 464 | ||
465 | extern struct mutex ecryptfs_daemon_hash_mux; | 465 | extern struct mutex ecryptfs_daemon_hash_mux; |
466 | 466 | ||
467 | static inline size_t | ||
468 | ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) | ||
469 | { | ||
470 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
471 | return 0; | ||
472 | return crypt_stat->metadata_size; | ||
473 | } | ||
474 | |||
467 | static inline struct ecryptfs_file_info * | 475 | static inline struct ecryptfs_file_info * |
468 | ecryptfs_file_to_private(struct file *file) | 476 | ecryptfs_file_to_private(struct file *file) |
469 | { | 477 | { |
@@ -651,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page); | |||
651 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); | 659 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); |
652 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); | 660 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); |
653 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | 661 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); |
662 | void ecryptfs_write_crypt_stat_flags(char *page_virt, | ||
663 | struct ecryptfs_crypt_stat *crypt_stat, | ||
664 | size_t *written); | ||
654 | int ecryptfs_read_and_validate_header_region(char *data, | 665 | int ecryptfs_read_and_validate_header_region(char *data, |
655 | struct inode *ecryptfs_inode); | 666 | struct inode *ecryptfs_inode); |
656 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 667 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index d3362faf3852..e2d4418affac 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -324,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
324 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 324 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
325 | ecryptfs_dentry->d_inode); | 325 | ecryptfs_dentry->d_inode); |
326 | if (rc) { | 326 | if (rc) { |
327 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
327 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, | 328 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, |
328 | ecryptfs_dentry); | 329 | ecryptfs_dentry); |
329 | if (rc) { | 330 | if (rc) { |
@@ -336,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
336 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 337 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
337 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | 338 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { |
338 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 339 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
339 | file_size = (crypt_stat->num_header_bytes_at_front | 340 | file_size = (crypt_stat->metadata_size |
340 | + i_size_read(lower_dentry->d_inode)); | 341 | + i_size_read(lower_dentry->d_inode)); |
341 | else | 342 | else |
342 | file_size = i_size_read(lower_dentry->d_inode); | 343 | file_size = i_size_read(lower_dentry->d_inode); |
@@ -388,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
388 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 389 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
389 | if (IS_ERR(lower_dentry)) { | 390 | if (IS_ERR(lower_dentry)) { |
390 | rc = PTR_ERR(lower_dentry); | 391 | rc = PTR_ERR(lower_dentry); |
391 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 392 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
392 | "lower_dentry = [%s]\n", __func__, rc, | 393 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
393 | ecryptfs_dentry->d_name.name); | 394 | encrypted_and_encoded_name); |
394 | goto out_d_drop; | 395 | goto out_d_drop; |
395 | } | 396 | } |
396 | if (lower_dentry->d_inode) | 397 | if (lower_dentry->d_inode) |
@@ -417,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
417 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); | 418 | mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
418 | if (IS_ERR(lower_dentry)) { | 419 | if (IS_ERR(lower_dentry)) { |
419 | rc = PTR_ERR(lower_dentry); | 420 | rc = PTR_ERR(lower_dentry); |
420 | printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " | 421 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
421 | "lower_dentry = [%s]\n", __func__, rc, | 422 | "[%d] on lower_dentry = [%s]\n", __func__, rc, |
422 | encrypted_and_encoded_name); | 423 | encrypted_and_encoded_name); |
423 | goto out_d_drop; | 424 | goto out_d_drop; |
424 | } | 425 | } |
425 | lookup_and_interpose: | 426 | lookup_and_interpose: |
@@ -456,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir, | |||
456 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); | 457 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); |
457 | if (rc) | 458 | if (rc) |
458 | goto out_lock; | 459 | goto out_lock; |
459 | fsstack_copy_attr_times(dir, lower_new_dentry->d_inode); | 460 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
460 | fsstack_copy_inode_size(dir, lower_new_dentry->d_inode); | 461 | fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
461 | old_dentry->d_inode->i_nlink = | 462 | old_dentry->d_inode->i_nlink = |
462 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; | 463 | ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink; |
463 | i_size_write(new_dentry->d_inode, file_size_save); | 464 | i_size_write(new_dentry->d_inode, file_size_save); |
@@ -648,38 +649,17 @@ out_lock: | |||
648 | return rc; | 649 | return rc; |
649 | } | 650 | } |
650 | 651 | ||
651 | static int | 652 | static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, |
652 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | 653 | size_t *bufsiz) |
653 | { | 654 | { |
655 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
654 | char *lower_buf; | 656 | char *lower_buf; |
655 | size_t lower_bufsiz; | 657 | size_t lower_bufsiz = PATH_MAX; |
656 | struct dentry *lower_dentry; | ||
657 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
658 | char *plaintext_name; | ||
659 | size_t plaintext_name_size; | ||
660 | mm_segment_t old_fs; | 658 | mm_segment_t old_fs; |
661 | int rc; | 659 | int rc; |
662 | 660 | ||
663 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
664 | if (!lower_dentry->d_inode->i_op->readlink) { | ||
665 | rc = -EINVAL; | ||
666 | goto out; | ||
667 | } | ||
668 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
669 | dentry->d_sb)->mount_crypt_stat; | ||
670 | /* | ||
671 | * If the lower filename is encrypted, it will result in a significantly | ||
672 | * longer name. If needed, truncate the name after decode and decrypt. | ||
673 | */ | ||
674 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) | ||
675 | lower_bufsiz = PATH_MAX; | ||
676 | else | ||
677 | lower_bufsiz = bufsiz; | ||
678 | /* Released in this function */ | ||
679 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); | 661 | lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); |
680 | if (lower_buf == NULL) { | 662 | if (!lower_buf) { |
681 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
682 | "kmalloc [%zd] bytes\n", __func__, lower_bufsiz); | ||
683 | rc = -ENOMEM; | 663 | rc = -ENOMEM; |
684 | goto out; | 664 | goto out; |
685 | } | 665 | } |
@@ -689,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | |||
689 | (char __user *)lower_buf, | 669 | (char __user *)lower_buf, |
690 | lower_bufsiz); | 670 | lower_bufsiz); |
691 | set_fs(old_fs); | 671 | set_fs(old_fs); |
692 | if (rc >= 0) { | 672 | if (rc < 0) |
693 | rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, | 673 | goto out; |
694 | &plaintext_name_size, | 674 | lower_bufsiz = rc; |
695 | dentry, lower_buf, | 675 | rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, |
696 | rc); | 676 | lower_buf, lower_bufsiz); |
697 | if (rc) { | 677 | out: |
698 | printk(KERN_ERR "%s: Error attempting to decode and " | ||
699 | "decrypt filename; rc = [%d]\n", __func__, | ||
700 | rc); | ||
701 | goto out_free_lower_buf; | ||
702 | } | ||
703 | /* Check for bufsiz <= 0 done in sys_readlinkat() */ | ||
704 | rc = copy_to_user(buf, plaintext_name, | ||
705 | min((size_t) bufsiz, plaintext_name_size)); | ||
706 | if (rc) | ||
707 | rc = -EFAULT; | ||
708 | else | ||
709 | rc = plaintext_name_size; | ||
710 | kfree(plaintext_name); | ||
711 | fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); | ||
712 | } | ||
713 | out_free_lower_buf: | ||
714 | kfree(lower_buf); | 678 | kfree(lower_buf); |
679 | return rc; | ||
680 | } | ||
681 | |||
682 | static int | ||
683 | ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) | ||
684 | { | ||
685 | char *kbuf; | ||
686 | size_t kbufsiz, copied; | ||
687 | int rc; | ||
688 | |||
689 | rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); | ||
690 | if (rc) | ||
691 | goto out; | ||
692 | copied = min_t(size_t, bufsiz, kbufsiz); | ||
693 | rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied; | ||
694 | kfree(kbuf); | ||
695 | fsstack_copy_attr_atime(dentry->d_inode, | ||
696 | ecryptfs_dentry_to_lower(dentry)->d_inode); | ||
715 | out: | 697 | out: |
716 | return rc; | 698 | return rc; |
717 | } | 699 | } |
@@ -769,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | |||
769 | { | 751 | { |
770 | loff_t lower_size; | 752 | loff_t lower_size; |
771 | 753 | ||
772 | lower_size = crypt_stat->num_header_bytes_at_front; | 754 | lower_size = ecryptfs_lower_header_size(crypt_stat); |
773 | if (upper_size != 0) { | 755 | if (upper_size != 0) { |
774 | loff_t num_extents; | 756 | loff_t num_extents; |
775 | 757 | ||
@@ -1016,6 +998,28 @@ out: | |||
1016 | return rc; | 998 | return rc; |
1017 | } | 999 | } |
1018 | 1000 | ||
1001 | int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry, | ||
1002 | struct kstat *stat) | ||
1003 | { | ||
1004 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
1005 | int rc = 0; | ||
1006 | |||
1007 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
1008 | dentry->d_sb)->mount_crypt_stat; | ||
1009 | generic_fillattr(dentry->d_inode, stat); | ||
1010 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { | ||
1011 | char *target; | ||
1012 | size_t targetsiz; | ||
1013 | |||
1014 | rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz); | ||
1015 | if (!rc) { | ||
1016 | kfree(target); | ||
1017 | stat->size = targetsiz; | ||
1018 | } | ||
1019 | } | ||
1020 | return rc; | ||
1021 | } | ||
1022 | |||
1019 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 1023 | int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1020 | struct kstat *stat) | 1024 | struct kstat *stat) |
1021 | { | 1025 | { |
@@ -1040,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
1040 | 1044 | ||
1041 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1045 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1042 | if (!lower_dentry->d_inode->i_op->setxattr) { | 1046 | if (!lower_dentry->d_inode->i_op->setxattr) { |
1043 | rc = -ENOSYS; | 1047 | rc = -EOPNOTSUPP; |
1044 | goto out; | 1048 | goto out; |
1045 | } | 1049 | } |
1046 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1050 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1058,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | |||
1058 | int rc = 0; | 1062 | int rc = 0; |
1059 | 1063 | ||
1060 | if (!lower_dentry->d_inode->i_op->getxattr) { | 1064 | if (!lower_dentry->d_inode->i_op->getxattr) { |
1061 | rc = -ENOSYS; | 1065 | rc = -EOPNOTSUPP; |
1062 | goto out; | 1066 | goto out; |
1063 | } | 1067 | } |
1064 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1068 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1085,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) | |||
1085 | 1089 | ||
1086 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1090 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1087 | if (!lower_dentry->d_inode->i_op->listxattr) { | 1091 | if (!lower_dentry->d_inode->i_op->listxattr) { |
1088 | rc = -ENOSYS; | 1092 | rc = -EOPNOTSUPP; |
1089 | goto out; | 1093 | goto out; |
1090 | } | 1094 | } |
1091 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1095 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1102,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name) | |||
1102 | 1106 | ||
1103 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 1107 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
1104 | if (!lower_dentry->d_inode->i_op->removexattr) { | 1108 | if (!lower_dentry->d_inode->i_op->removexattr) { |
1105 | rc = -ENOSYS; | 1109 | rc = -EOPNOTSUPP; |
1106 | goto out; | 1110 | goto out; |
1107 | } | 1111 | } |
1108 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 1112 | mutex_lock(&lower_dentry->d_inode->i_mutex); |
@@ -1133,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = { | |||
1133 | .put_link = ecryptfs_put_link, | 1137 | .put_link = ecryptfs_put_link, |
1134 | .permission = ecryptfs_permission, | 1138 | .permission = ecryptfs_permission, |
1135 | .setattr = ecryptfs_setattr, | 1139 | .setattr = ecryptfs_setattr, |
1140 | .getattr = ecryptfs_getattr_link, | ||
1136 | .setxattr = ecryptfs_setxattr, | 1141 | .setxattr = ecryptfs_setxattr, |
1137 | .getxattr = ecryptfs_getxattr, | 1142 | .getxattr = ecryptfs_getxattr, |
1138 | .listxattr = ecryptfs_listxattr, | 1143 | .listxattr = ecryptfs_listxattr, |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index d491237c98e7..2ee9a3a7b68c 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -83,6 +83,19 @@ out: | |||
83 | return rc; | 83 | return rc; |
84 | } | 84 | } |
85 | 85 | ||
86 | static void strip_xattr_flag(char *page_virt, | ||
87 | struct ecryptfs_crypt_stat *crypt_stat) | ||
88 | { | ||
89 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
90 | size_t written; | ||
91 | |||
92 | crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR; | ||
93 | ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat, | ||
94 | &written); | ||
95 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | ||
96 | } | ||
97 | } | ||
98 | |||
86 | /** | 99 | /** |
87 | * Header Extent: | 100 | * Header Extent: |
88 | * Octets 0-7: Unencrypted file size (big-endian) | 101 | * Octets 0-7: Unencrypted file size (big-endian) |
@@ -98,19 +111,6 @@ out: | |||
98 | * (big-endian) | 111 | * (big-endian) |
99 | * Octet 26: Begin RFC 2440 authentication token packet set | 112 | * Octet 26: Begin RFC 2440 authentication token packet set |
100 | */ | 113 | */ |
101 | static void set_header_info(char *page_virt, | ||
102 | struct ecryptfs_crypt_stat *crypt_stat) | ||
103 | { | ||
104 | size_t written; | ||
105 | size_t save_num_header_bytes_at_front = | ||
106 | crypt_stat->num_header_bytes_at_front; | ||
107 | |||
108 | crypt_stat->num_header_bytes_at_front = | ||
109 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
110 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); | ||
111 | crypt_stat->num_header_bytes_at_front = | ||
112 | save_num_header_bytes_at_front; | ||
113 | } | ||
114 | 114 | ||
115 | /** | 115 | /** |
116 | * ecryptfs_copy_up_encrypted_with_header | 116 | * ecryptfs_copy_up_encrypted_with_header |
@@ -136,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
136 | * num_extents_per_page) | 136 | * num_extents_per_page) |
137 | + extent_num_in_page); | 137 | + extent_num_in_page); |
138 | size_t num_header_extents_at_front = | 138 | size_t num_header_extents_at_front = |
139 | (crypt_stat->num_header_bytes_at_front | 139 | (crypt_stat->metadata_size / crypt_stat->extent_size); |
140 | / crypt_stat->extent_size); | ||
141 | 140 | ||
142 | if (view_extent_num < num_header_extents_at_front) { | 141 | if (view_extent_num < num_header_extents_at_front) { |
143 | /* This is a header extent */ | 142 | /* This is a header extent */ |
@@ -147,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
147 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 146 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
148 | /* TODO: Support more than one header extent */ | 147 | /* TODO: Support more than one header extent */ |
149 | if (view_extent_num == 0) { | 148 | if (view_extent_num == 0) { |
149 | size_t written; | ||
150 | |||
150 | rc = ecryptfs_read_xattr_region( | 151 | rc = ecryptfs_read_xattr_region( |
151 | page_virt, page->mapping->host); | 152 | page_virt, page->mapping->host); |
152 | set_header_info(page_virt, crypt_stat); | 153 | strip_xattr_flag(page_virt + 16, crypt_stat); |
154 | ecryptfs_write_header_metadata(page_virt + 20, | ||
155 | crypt_stat, | ||
156 | &written); | ||
153 | } | 157 | } |
154 | kunmap_atomic(page_virt, KM_USER0); | 158 | kunmap_atomic(page_virt, KM_USER0); |
155 | flush_dcache_page(page); | 159 | flush_dcache_page(page); |
@@ -162,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
162 | /* This is an encrypted data extent */ | 166 | /* This is an encrypted data extent */ |
163 | loff_t lower_offset = | 167 | loff_t lower_offset = |
164 | ((view_extent_num * crypt_stat->extent_size) | 168 | ((view_extent_num * crypt_stat->extent_size) |
165 | - crypt_stat->num_header_bytes_at_front); | 169 | - crypt_stat->metadata_size); |
166 | 170 | ||
167 | rc = ecryptfs_read_lower_page_segment( | 171 | rc = ecryptfs_read_lower_page_segment( |
168 | page, (lower_offset >> PAGE_CACHE_SHIFT), | 172 | page, (lower_offset >> PAGE_CACHE_SHIFT), |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index fcef41c1d2cf..278743c7716a 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode) | |||
86 | if (lower_dentry->d_inode) { | 86 | if (lower_dentry->d_inode) { |
87 | fput(inode_info->lower_file); | 87 | fput(inode_info->lower_file); |
88 | inode_info->lower_file = NULL; | 88 | inode_info->lower_file = NULL; |
89 | d_drop(lower_dentry); | ||
90 | } | 89 | } |
91 | } | 90 | } |
92 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); | 91 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); |
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 4e2426e22bbe..565cf817bbf1 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c | |||
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
32 | .readlink = generic_readlink, | 32 | .readlink = generic_readlink, |
33 | .follow_link = page_follow_link_light, | 33 | .follow_link = page_follow_link_light, |
34 | .put_link = page_put_link, | 34 | .put_link = page_put_link, |
35 | .setattr = ext2_setattr, | ||
35 | #ifdef CONFIG_EXT2_FS_XATTR | 36 | #ifdef CONFIG_EXT2_FS_XATTR |
36 | .setxattr = generic_setxattr, | 37 | .setxattr = generic_setxattr, |
37 | .getxattr = generic_getxattr, | 38 | .getxattr = generic_getxattr, |
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
43 | const struct inode_operations ext2_fast_symlink_inode_operations = { | 44 | const struct inode_operations ext2_fast_symlink_inode_operations = { |
44 | .readlink = generic_readlink, | 45 | .readlink = generic_readlink, |
45 | .follow_link = ext2_follow_link, | 46 | .follow_link = ext2_follow_link, |
47 | .setattr = ext2_setattr, | ||
46 | #ifdef CONFIG_EXT2_FS_XATTR | 48 | #ifdef CONFIG_EXT2_FS_XATTR |
47 | .setxattr = generic_setxattr, | 49 | .setxattr = generic_setxattr, |
48 | .getxattr = generic_getxattr, | 50 | .getxattr = generic_getxattr, |
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c index ff7b4ccd8983..7c4898207776 100644 --- a/fs/ext3/symlink.c +++ b/fs/ext3/symlink.c | |||
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = { | |||
34 | .readlink = generic_readlink, | 34 | .readlink = generic_readlink, |
35 | .follow_link = page_follow_link_light, | 35 | .follow_link = page_follow_link_light, |
36 | .put_link = page_put_link, | 36 | .put_link = page_put_link, |
37 | .setattr = ext3_setattr, | ||
37 | #ifdef CONFIG_EXT3_FS_XATTR | 38 | #ifdef CONFIG_EXT3_FS_XATTR |
38 | .setxattr = generic_setxattr, | 39 | .setxattr = generic_setxattr, |
39 | .getxattr = generic_getxattr, | 40 | .getxattr = generic_getxattr, |
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = { | |||
45 | const struct inode_operations ext3_fast_symlink_inode_operations = { | 46 | const struct inode_operations ext3_fast_symlink_inode_operations = { |
46 | .readlink = generic_readlink, | 47 | .readlink = generic_readlink, |
47 | .follow_link = ext3_follow_link, | 48 | .follow_link = ext3_follow_link, |
49 | .setattr = ext3_setattr, | ||
48 | #ifdef CONFIG_EXT3_FS_XATTR | 50 | #ifdef CONFIG_EXT3_FS_XATTR |
49 | .setxattr = generic_setxattr, | 51 | .setxattr = generic_setxattr, |
50 | .getxattr = generic_getxattr, | 52 | .getxattr = generic_getxattr, |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 781a322ccb45..4b37f7cea4dd 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -554,108 +554,85 @@ select_queue: | |||
554 | return ret; | 554 | return ret; |
555 | } | 555 | } |
556 | 556 | ||
557 | static void unpin_sb_for_writeback(struct super_block **psb) | 557 | static void unpin_sb_for_writeback(struct super_block *sb) |
558 | { | 558 | { |
559 | struct super_block *sb = *psb; | 559 | up_read(&sb->s_umount); |
560 | 560 | put_super(sb); | |
561 | if (sb) { | ||
562 | up_read(&sb->s_umount); | ||
563 | put_super(sb); | ||
564 | *psb = NULL; | ||
565 | } | ||
566 | } | 561 | } |
567 | 562 | ||
563 | enum sb_pin_state { | ||
564 | SB_PINNED, | ||
565 | SB_NOT_PINNED, | ||
566 | SB_PIN_FAILED | ||
567 | }; | ||
568 | |||
568 | /* | 569 | /* |
569 | * For WB_SYNC_NONE writeback, the caller does not have the sb pinned | 570 | * For WB_SYNC_NONE writeback, the caller does not have the sb pinned |
570 | * before calling writeback. So make sure that we do pin it, so it doesn't | 571 | * before calling writeback. So make sure that we do pin it, so it doesn't |
571 | * go away while we are writing inodes from it. | 572 | * go away while we are writing inodes from it. |
572 | * | ||
573 | * Returns 0 if the super was successfully pinned (or pinning wasn't needed), | ||
574 | * 1 if we failed. | ||
575 | */ | 573 | */ |
576 | static int pin_sb_for_writeback(struct writeback_control *wbc, | 574 | static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, |
577 | struct inode *inode, struct super_block **psb) | 575 | struct super_block *sb) |
578 | { | 576 | { |
579 | struct super_block *sb = inode->i_sb; | ||
580 | |||
581 | /* | ||
582 | * If this sb is already pinned, nothing more to do. If not and | ||
583 | * *psb is non-NULL, unpin the old one first | ||
584 | */ | ||
585 | if (sb == *psb) | ||
586 | return 0; | ||
587 | else if (*psb) | ||
588 | unpin_sb_for_writeback(psb); | ||
589 | |||
590 | /* | 577 | /* |
591 | * Caller must already hold the ref for this | 578 | * Caller must already hold the ref for this |
592 | */ | 579 | */ |
593 | if (wbc->sync_mode == WB_SYNC_ALL) { | 580 | if (wbc->sync_mode == WB_SYNC_ALL) { |
594 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | 581 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
595 | return 0; | 582 | return SB_NOT_PINNED; |
596 | } | 583 | } |
597 | |||
598 | spin_lock(&sb_lock); | 584 | spin_lock(&sb_lock); |
599 | sb->s_count++; | 585 | sb->s_count++; |
600 | if (down_read_trylock(&sb->s_umount)) { | 586 | if (down_read_trylock(&sb->s_umount)) { |
601 | if (sb->s_root) { | 587 | if (sb->s_root) { |
602 | spin_unlock(&sb_lock); | 588 | spin_unlock(&sb_lock); |
603 | goto pinned; | 589 | return SB_PINNED; |
604 | } | 590 | } |
605 | /* | 591 | /* |
606 | * umounted, drop rwsem again and fall through to failure | 592 | * umounted, drop rwsem again and fall through to failure |
607 | */ | 593 | */ |
608 | up_read(&sb->s_umount); | 594 | up_read(&sb->s_umount); |
609 | } | 595 | } |
610 | |||
611 | sb->s_count--; | 596 | sb->s_count--; |
612 | spin_unlock(&sb_lock); | 597 | spin_unlock(&sb_lock); |
613 | return 1; | 598 | return SB_PIN_FAILED; |
614 | pinned: | ||
615 | *psb = sb; | ||
616 | return 0; | ||
617 | } | 599 | } |
618 | 600 | ||
619 | static void writeback_inodes_wb(struct bdi_writeback *wb, | 601 | /* |
620 | struct writeback_control *wbc) | 602 | * Write a portion of b_io inodes which belong to @sb. |
603 | * If @wbc->sb != NULL, then find and write all such | ||
604 | * inodes. Otherwise write only ones which go sequentially | ||
605 | * in reverse order. | ||
606 | * Return 1, if the caller writeback routine should be | ||
607 | * interrupted. Otherwise return 0. | ||
608 | */ | ||
609 | static int writeback_sb_inodes(struct super_block *sb, | ||
610 | struct bdi_writeback *wb, | ||
611 | struct writeback_control *wbc) | ||
621 | { | 612 | { |
622 | struct super_block *sb = wbc->sb, *pin_sb = NULL; | ||
623 | const unsigned long start = jiffies; /* livelock avoidance */ | ||
624 | |||
625 | spin_lock(&inode_lock); | ||
626 | |||
627 | if (!wbc->for_kupdate || list_empty(&wb->b_io)) | ||
628 | queue_io(wb, wbc->older_than_this); | ||
629 | |||
630 | while (!list_empty(&wb->b_io)) { | 613 | while (!list_empty(&wb->b_io)) { |
631 | struct inode *inode = list_entry(wb->b_io.prev, | ||
632 | struct inode, i_list); | ||
633 | long pages_skipped; | 614 | long pages_skipped; |
634 | 615 | struct inode *inode = list_entry(wb->b_io.prev, | |
635 | /* | 616 | struct inode, i_list); |
636 | * super block given and doesn't match, skip this inode | 617 | if (wbc->sb && sb != inode->i_sb) { |
637 | */ | 618 | /* super block given and doesn't |
638 | if (sb && sb != inode->i_sb) { | 619 | match, skip this inode */ |
639 | redirty_tail(inode); | 620 | redirty_tail(inode); |
640 | continue; | 621 | continue; |
641 | } | 622 | } |
642 | 623 | if (sb != inode->i_sb) | |
624 | /* finish with this superblock */ | ||
625 | return 0; | ||
643 | if (inode->i_state & (I_NEW | I_WILL_FREE)) { | 626 | if (inode->i_state & (I_NEW | I_WILL_FREE)) { |
644 | requeue_io(inode); | 627 | requeue_io(inode); |
645 | continue; | 628 | continue; |
646 | } | 629 | } |
647 | |||
648 | /* | 630 | /* |
649 | * Was this inode dirtied after sync_sb_inodes was called? | 631 | * Was this inode dirtied after sync_sb_inodes was called? |
650 | * This keeps sync from extra jobs and livelock. | 632 | * This keeps sync from extra jobs and livelock. |
651 | */ | 633 | */ |
652 | if (inode_dirtied_after(inode, start)) | 634 | if (inode_dirtied_after(inode, wbc->wb_start)) |
653 | break; | 635 | return 1; |
654 | |||
655 | if (pin_sb_for_writeback(wbc, inode, &pin_sb)) { | ||
656 | requeue_io(inode); | ||
657 | continue; | ||
658 | } | ||
659 | 636 | ||
660 | BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); | 637 | BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); |
661 | __iget(inode); | 638 | __iget(inode); |
@@ -674,14 +651,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, | |||
674 | spin_lock(&inode_lock); | 651 | spin_lock(&inode_lock); |
675 | if (wbc->nr_to_write <= 0) { | 652 | if (wbc->nr_to_write <= 0) { |
676 | wbc->more_io = 1; | 653 | wbc->more_io = 1; |
677 | break; | 654 | return 1; |
678 | } | 655 | } |
679 | if (!list_empty(&wb->b_more_io)) | 656 | if (!list_empty(&wb->b_more_io)) |
680 | wbc->more_io = 1; | 657 | wbc->more_io = 1; |
681 | } | 658 | } |
659 | /* b_io is empty */ | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | static void writeback_inodes_wb(struct bdi_writeback *wb, | ||
664 | struct writeback_control *wbc) | ||
665 | { | ||
666 | int ret = 0; | ||
682 | 667 | ||
683 | unpin_sb_for_writeback(&pin_sb); | 668 | wbc->wb_start = jiffies; /* livelock avoidance */ |
669 | spin_lock(&inode_lock); | ||
670 | if (!wbc->for_kupdate || list_empty(&wb->b_io)) | ||
671 | queue_io(wb, wbc->older_than_this); | ||
672 | |||
673 | while (!list_empty(&wb->b_io)) { | ||
674 | struct inode *inode = list_entry(wb->b_io.prev, | ||
675 | struct inode, i_list); | ||
676 | struct super_block *sb = inode->i_sb; | ||
677 | enum sb_pin_state state; | ||
678 | |||
679 | if (wbc->sb && sb != wbc->sb) { | ||
680 | /* super block given and doesn't | ||
681 | match, skip this inode */ | ||
682 | redirty_tail(inode); | ||
683 | continue; | ||
684 | } | ||
685 | state = pin_sb_for_writeback(wbc, sb); | ||
686 | |||
687 | if (state == SB_PIN_FAILED) { | ||
688 | requeue_io(inode); | ||
689 | continue; | ||
690 | } | ||
691 | ret = writeback_sb_inodes(sb, wb, wbc); | ||
684 | 692 | ||
693 | if (state == SB_PINNED) | ||
694 | unpin_sb_for_writeback(sb); | ||
695 | if (ret) | ||
696 | break; | ||
697 | } | ||
685 | spin_unlock(&inode_lock); | 698 | spin_unlock(&inode_lock); |
686 | /* Leave any unwritten inodes on b_io */ | 699 | /* Leave any unwritten inodes on b_io */ |
687 | } | 700 | } |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 9dd126276c9f..ed9ba6fe04f5 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -61,7 +61,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino) | |||
61 | inode->i_op = &page_symlink_inode_operations; | 61 | inode->i_op = &page_symlink_inode_operations; |
62 | inode->i_mapping->a_ops = &jfs_aops; | 62 | inode->i_mapping->a_ops = &jfs_aops; |
63 | } else { | 63 | } else { |
64 | inode->i_op = &jfs_symlink_inode_operations; | 64 | inode->i_op = &jfs_fast_symlink_inode_operations; |
65 | /* | 65 | /* |
66 | * The inline data should be null-terminated, but | 66 | * The inline data should be null-terminated, but |
67 | * don't let on-disk corruption crash the kernel | 67 | * don't let on-disk corruption crash the kernel |
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 6c4dfcbf3f55..9e2f6a721668 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -196,7 +196,7 @@ int dbMount(struct inode *ipbmap) | |||
196 | bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); | 196 | bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); |
197 | bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); | 197 | bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); |
198 | bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); | 198 | bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); |
199 | bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth); | 199 | bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); |
200 | bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); | 200 | bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); |
201 | bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); | 201 | bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); |
202 | bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); | 202 | bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); |
@@ -288,7 +288,7 @@ int dbSync(struct inode *ipbmap) | |||
288 | dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag); | 288 | dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag); |
289 | dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref); | 289 | dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref); |
290 | dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel); | 290 | dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel); |
291 | dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth); | 291 | dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight); |
292 | dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth); | 292 | dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth); |
293 | dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart); | 293 | dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart); |
294 | dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size); | 294 | dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size); |
@@ -1441,7 +1441,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) | |||
1441 | * tree index of this allocation group within the control page. | 1441 | * tree index of this allocation group within the control page. |
1442 | */ | 1442 | */ |
1443 | agperlev = | 1443 | agperlev = |
1444 | (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth; | 1444 | (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth; |
1445 | ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); | 1445 | ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); |
1446 | 1446 | ||
1447 | /* dmap control page trees fan-out by 4 and a single allocation | 1447 | /* dmap control page trees fan-out by 4 and a single allocation |
@@ -1460,7 +1460,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) | |||
1460 | * the subtree to find the leftmost leaf that describes this | 1460 | * the subtree to find the leftmost leaf that describes this |
1461 | * free space. | 1461 | * free space. |
1462 | */ | 1462 | */ |
1463 | for (k = bmp->db_agheigth; k > 0; k--) { | 1463 | for (k = bmp->db_agheight; k > 0; k--) { |
1464 | for (n = 0, m = (ti << 2) + 1; n < 4; n++) { | 1464 | for (n = 0, m = (ti << 2) + 1; n < 4; n++) { |
1465 | if (l2nb <= dcp->stree[m + n]) { | 1465 | if (l2nb <= dcp->stree[m + n]) { |
1466 | ti = m + n; | 1466 | ti = m + n; |
@@ -3607,7 +3607,7 @@ void dbFinalizeBmap(struct inode *ipbmap) | |||
3607 | } | 3607 | } |
3608 | 3608 | ||
3609 | /* | 3609 | /* |
3610 | * compute db_aglevel, db_agheigth, db_width, db_agstart: | 3610 | * compute db_aglevel, db_agheight, db_width, db_agstart: |
3611 | * an ag is covered in aglevel dmapctl summary tree, | 3611 | * an ag is covered in aglevel dmapctl summary tree, |
3612 | * at agheight level height (from leaf) with agwidth number of nodes | 3612 | * at agheight level height (from leaf) with agwidth number of nodes |
3613 | * each, which starts at agstart index node of the smmary tree node | 3613 | * each, which starts at agstart index node of the smmary tree node |
@@ -3616,9 +3616,9 @@ void dbFinalizeBmap(struct inode *ipbmap) | |||
3616 | bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize); | 3616 | bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize); |
3617 | l2nl = | 3617 | l2nl = |
3618 | bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL); | 3618 | bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL); |
3619 | bmp->db_agheigth = l2nl >> 1; | 3619 | bmp->db_agheight = l2nl >> 1; |
3620 | bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1)); | 3620 | bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1)); |
3621 | for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0; | 3621 | for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0; |
3622 | i--) { | 3622 | i--) { |
3623 | bmp->db_agstart += n; | 3623 | bmp->db_agstart += n; |
3624 | n <<= 2; | 3624 | n <<= 2; |
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h index 1a6eb41569bc..6dcb906c55d8 100644 --- a/fs/jfs/jfs_dmap.h +++ b/fs/jfs/jfs_dmap.h | |||
@@ -210,7 +210,7 @@ struct dbmap_disk { | |||
210 | __le32 dn_maxag; /* 4: max active alloc group number */ | 210 | __le32 dn_maxag; /* 4: max active alloc group number */ |
211 | __le32 dn_agpref; /* 4: preferred alloc group (hint) */ | 211 | __le32 dn_agpref; /* 4: preferred alloc group (hint) */ |
212 | __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ | 212 | __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ |
213 | __le32 dn_agheigth; /* 4: height in dmapctl of the AG */ | 213 | __le32 dn_agheight; /* 4: height in dmapctl of the AG */ |
214 | __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ | 214 | __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ |
215 | __le32 dn_agstart; /* 4: start tree index at AG height */ | 215 | __le32 dn_agstart; /* 4: start tree index at AG height */ |
216 | __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ | 216 | __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ |
@@ -229,7 +229,7 @@ struct dbmap { | |||
229 | int dn_maxag; /* max active alloc group number */ | 229 | int dn_maxag; /* max active alloc group number */ |
230 | int dn_agpref; /* preferred alloc group (hint) */ | 230 | int dn_agpref; /* preferred alloc group (hint) */ |
231 | int dn_aglevel; /* dmapctl level holding the AG */ | 231 | int dn_aglevel; /* dmapctl level holding the AG */ |
232 | int dn_agheigth; /* height in dmapctl of the AG */ | 232 | int dn_agheight; /* height in dmapctl of the AG */ |
233 | int dn_agwidth; /* width in dmapctl of the AG */ | 233 | int dn_agwidth; /* width in dmapctl of the AG */ |
234 | int dn_agstart; /* start tree index at AG height */ | 234 | int dn_agstart; /* start tree index at AG height */ |
235 | int dn_agl2size; /* l2 num of blks per alloc group */ | 235 | int dn_agl2size; /* l2 num of blks per alloc group */ |
@@ -255,7 +255,7 @@ struct bmap { | |||
255 | #define db_agsize db_bmap.dn_agsize | 255 | #define db_agsize db_bmap.dn_agsize |
256 | #define db_agl2size db_bmap.dn_agl2size | 256 | #define db_agl2size db_bmap.dn_agl2size |
257 | #define db_agwidth db_bmap.dn_agwidth | 257 | #define db_agwidth db_bmap.dn_agwidth |
258 | #define db_agheigth db_bmap.dn_agheigth | 258 | #define db_agheight db_bmap.dn_agheight |
259 | #define db_agstart db_bmap.dn_agstart | 259 | #define db_agstart db_bmap.dn_agstart |
260 | #define db_numag db_bmap.dn_numag | 260 | #define db_numag db_bmap.dn_numag |
261 | #define db_maxlevel db_bmap.dn_maxlevel | 261 | #define db_maxlevel db_bmap.dn_maxlevel |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 79e2c79661df..9e6bda30a6e8 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -48,5 +48,6 @@ extern const struct file_operations jfs_dir_operations; | |||
48 | extern const struct inode_operations jfs_file_inode_operations; | 48 | extern const struct inode_operations jfs_file_inode_operations; |
49 | extern const struct file_operations jfs_file_operations; | 49 | extern const struct file_operations jfs_file_operations; |
50 | extern const struct inode_operations jfs_symlink_inode_operations; | 50 | extern const struct inode_operations jfs_symlink_inode_operations; |
51 | extern const struct inode_operations jfs_fast_symlink_inode_operations; | ||
51 | extern const struct dentry_operations jfs_ci_dentry_operations; | 52 | extern const struct dentry_operations jfs_ci_dentry_operations; |
52 | #endif /* _H_JFS_INODE */ | 53 | #endif /* _H_JFS_INODE */ |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 4a3e9f39c21d..a9cf8e8675be 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -956,7 +956,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
956 | */ | 956 | */ |
957 | 957 | ||
958 | if (ssize <= IDATASIZE) { | 958 | if (ssize <= IDATASIZE) { |
959 | ip->i_op = &jfs_symlink_inode_operations; | 959 | ip->i_op = &jfs_fast_symlink_inode_operations; |
960 | 960 | ||
961 | i_fastsymlink = JFS_IP(ip)->i_inline; | 961 | i_fastsymlink = JFS_IP(ip)->i_inline; |
962 | memcpy(i_fastsymlink, name, ssize); | 962 | memcpy(i_fastsymlink, name, ssize); |
@@ -978,7 +978,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
978 | else { | 978 | else { |
979 | jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); | 979 | jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); |
980 | 980 | ||
981 | ip->i_op = &page_symlink_inode_operations; | 981 | ip->i_op = &jfs_symlink_inode_operations; |
982 | ip->i_mapping->a_ops = &jfs_aops; | 982 | ip->i_mapping->a_ops = &jfs_aops; |
983 | 983 | ||
984 | /* | 984 | /* |
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c index 7f24a0bb08ca..1aba0039f1c9 100644 --- a/fs/jfs/resize.c +++ b/fs/jfs/resize.c | |||
@@ -81,6 +81,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) | |||
81 | struct inode *iplist[1]; | 81 | struct inode *iplist[1]; |
82 | struct jfs_superblock *j_sb, *j_sb2; | 82 | struct jfs_superblock *j_sb, *j_sb2; |
83 | uint old_agsize; | 83 | uint old_agsize; |
84 | int agsizechanged = 0; | ||
84 | struct buffer_head *bh, *bh2; | 85 | struct buffer_head *bh, *bh2; |
85 | 86 | ||
86 | /* If the volume hasn't grown, get out now */ | 87 | /* If the volume hasn't grown, get out now */ |
@@ -333,6 +334,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) | |||
333 | */ | 334 | */ |
334 | if ((rc = dbExtendFS(ipbmap, XAddress, nblocks))) | 335 | if ((rc = dbExtendFS(ipbmap, XAddress, nblocks))) |
335 | goto error_out; | 336 | goto error_out; |
337 | |||
338 | agsizechanged |= (bmp->db_agsize != old_agsize); | ||
339 | |||
336 | /* | 340 | /* |
337 | * the map now has extended to cover additional nblocks: | 341 | * the map now has extended to cover additional nblocks: |
338 | * dn_mapsize = oldMapsize + nblocks; | 342 | * dn_mapsize = oldMapsize + nblocks; |
@@ -432,7 +436,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) | |||
432 | * will correctly identify the new ag); | 436 | * will correctly identify the new ag); |
433 | */ | 437 | */ |
434 | /* if new AG size the same as old AG size, done! */ | 438 | /* if new AG size the same as old AG size, done! */ |
435 | if (bmp->db_agsize != old_agsize) { | 439 | if (agsizechanged) { |
436 | if ((rc = diExtendFS(ipimap, ipbmap))) | 440 | if ((rc = diExtendFS(ipimap, ipbmap))) |
437 | goto error_out; | 441 | goto error_out; |
438 | 442 | ||
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 4af1a05aad0a..205b946d8e0d 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c | |||
@@ -29,9 +29,21 @@ static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
29 | return NULL; | 29 | return NULL; |
30 | } | 30 | } |
31 | 31 | ||
32 | const struct inode_operations jfs_symlink_inode_operations = { | 32 | const struct inode_operations jfs_fast_symlink_inode_operations = { |
33 | .readlink = generic_readlink, | 33 | .readlink = generic_readlink, |
34 | .follow_link = jfs_follow_link, | 34 | .follow_link = jfs_follow_link, |
35 | .setattr = jfs_setattr, | ||
36 | .setxattr = jfs_setxattr, | ||
37 | .getxattr = jfs_getxattr, | ||
38 | .listxattr = jfs_listxattr, | ||
39 | .removexattr = jfs_removexattr, | ||
40 | }; | ||
41 | |||
42 | const struct inode_operations jfs_symlink_inode_operations = { | ||
43 | .readlink = generic_readlink, | ||
44 | .follow_link = page_follow_link_light, | ||
45 | .put_link = page_put_link, | ||
46 | .setattr = jfs_setattr, | ||
35 | .setxattr = jfs_setxattr, | 47 | .setxattr = jfs_setxattr, |
36 | .getxattr = jfs_getxattr, | 48 | .getxattr = jfs_getxattr, |
37 | .listxattr = jfs_listxattr, | 49 | .listxattr = jfs_listxattr, |
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c index 84e36f52fe95..76c242fbe1b0 100644 --- a/fs/logfs/gc.c +++ b/fs/logfs/gc.c | |||
@@ -459,6 +459,14 @@ static void __logfs_gc_pass(struct super_block *sb, int target) | |||
459 | struct logfs_block *block; | 459 | struct logfs_block *block; |
460 | int round, progress, last_progress = 0; | 460 | int round, progress, last_progress = 0; |
461 | 461 | ||
462 | /* | ||
463 | * Doing too many changes to the segfile at once would result | ||
464 | * in a large number of aliases. Write the journal before | ||
465 | * things get out of hand. | ||
466 | */ | ||
467 | if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES) | ||
468 | logfs_write_anchor(sb); | ||
469 | |||
462 | if (no_free_segments(sb) >= target && | 470 | if (no_free_segments(sb) >= target && |
463 | super->s_no_object_aliases < MAX_OBJ_ALIASES) | 471 | super->s_no_object_aliases < MAX_OBJ_ALIASES) |
464 | return; | 472 | return; |
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 33bd260b8309..fb0a613f885b 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
@@ -389,7 +389,10 @@ static void journal_get_erase_count(struct logfs_area *area) | |||
389 | static int journal_erase_segment(struct logfs_area *area) | 389 | static int journal_erase_segment(struct logfs_area *area) |
390 | { | 390 | { |
391 | struct super_block *sb = area->a_sb; | 391 | struct super_block *sb = area->a_sb; |
392 | struct logfs_segment_header sh; | 392 | union { |
393 | struct logfs_segment_header sh; | ||
394 | unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)]; | ||
395 | } u; | ||
393 | u64 ofs; | 396 | u64 ofs; |
394 | int err; | 397 | int err; |
395 | 398 | ||
@@ -397,20 +400,21 @@ static int journal_erase_segment(struct logfs_area *area) | |||
397 | if (err) | 400 | if (err) |
398 | return err; | 401 | return err; |
399 | 402 | ||
400 | sh.pad = 0; | 403 | memset(&u, 0, sizeof(u)); |
401 | sh.type = SEG_JOURNAL; | 404 | u.sh.pad = 0; |
402 | sh.level = 0; | 405 | u.sh.type = SEG_JOURNAL; |
403 | sh.segno = cpu_to_be32(area->a_segno); | 406 | u.sh.level = 0; |
404 | sh.ec = cpu_to_be32(area->a_erase_count); | 407 | u.sh.segno = cpu_to_be32(area->a_segno); |
405 | sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); | 408 | u.sh.ec = cpu_to_be32(area->a_erase_count); |
406 | sh.crc = logfs_crc32(&sh, sizeof(sh), 4); | 409 | u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); |
410 | u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4); | ||
407 | 411 | ||
408 | /* This causes a bug in segment.c. Not yet. */ | 412 | /* This causes a bug in segment.c. Not yet. */ |
409 | //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0); | 413 | //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0); |
410 | 414 | ||
411 | ofs = dev_ofs(sb, area->a_segno, 0); | 415 | ofs = dev_ofs(sb, area->a_segno, 0); |
412 | area->a_used_bytes = ALIGN(sizeof(sh), 16); | 416 | area->a_used_bytes = sizeof(u); |
413 | logfs_buf_write(area, ofs, &sh, sizeof(sh)); | 417 | logfs_buf_write(area, ofs, &u, sizeof(u)); |
414 | return 0; | 418 | return 0; |
415 | } | 419 | } |
416 | 420 | ||
@@ -494,6 +498,8 @@ static void account_shadows(struct super_block *sb) | |||
494 | 498 | ||
495 | btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow); | 499 | btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow); |
496 | btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow); | 500 | btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow); |
501 | btree_grim_visitor32(&tree->segment_map, 0, NULL); | ||
502 | tree->no_shadowed_segments = 0; | ||
497 | 503 | ||
498 | if (li->li_block) { | 504 | if (li->li_block) { |
499 | /* | 505 | /* |
@@ -607,9 +613,9 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type, | |||
607 | if (len == 0) | 613 | if (len == 0) |
608 | return logfs_write_header(super, header, 0, type); | 614 | return logfs_write_header(super, header, 0, type); |
609 | 615 | ||
616 | BUG_ON(len > sb->s_blocksize); | ||
610 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); | 617 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); |
611 | if (compr_len < 0 || type == JE_ANCHOR) { | 618 | if (compr_len < 0 || type == JE_ANCHOR) { |
612 | BUG_ON(len > sb->s_blocksize); | ||
613 | memcpy(data, buf, len); | 619 | memcpy(data, buf, len); |
614 | compr_len = len; | 620 | compr_len = len; |
615 | compr = COMPR_NONE; | 621 | compr = COMPR_NONE; |
@@ -661,6 +667,7 @@ static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type, | |||
661 | if (ofs < 0) | 667 | if (ofs < 0) |
662 | return ofs; | 668 | return ofs; |
663 | logfs_buf_write(area, ofs, super->s_compressed_je, len); | 669 | logfs_buf_write(area, ofs, super->s_compressed_je, len); |
670 | BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES); | ||
664 | super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs); | 671 | super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs); |
665 | return 0; | 672 | return 0; |
666 | } | 673 | } |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index b84b0eec6024..0a3df1a0c936 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -257,10 +257,14 @@ struct logfs_shadow { | |||
257 | * struct shadow_tree | 257 | * struct shadow_tree |
258 | * @new: shadows where old_ofs==0, indexed by new_ofs | 258 | * @new: shadows where old_ofs==0, indexed by new_ofs |
259 | * @old: shadows where old_ofs!=0, indexed by old_ofs | 259 | * @old: shadows where old_ofs!=0, indexed by old_ofs |
260 | * @segment_map: bitfield of segments containing shadows | ||
261 | * @no_shadowed_segment: number of segments containing shadows | ||
260 | */ | 262 | */ |
261 | struct shadow_tree { | 263 | struct shadow_tree { |
262 | struct btree_head64 new; | 264 | struct btree_head64 new; |
263 | struct btree_head64 old; | 265 | struct btree_head64 old; |
266 | struct btree_head32 segment_map; | ||
267 | int no_shadowed_segments; | ||
264 | }; | 268 | }; |
265 | 269 | ||
266 | struct object_alias_item { | 270 | struct object_alias_item { |
@@ -305,13 +309,14 @@ typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix, | |||
305 | level_t level, int child_no, __be64 val); | 309 | level_t level, int child_no, __be64 val); |
306 | struct logfs_block_ops { | 310 | struct logfs_block_ops { |
307 | void (*write_block)(struct logfs_block *block); | 311 | void (*write_block)(struct logfs_block *block); |
308 | gc_level_t (*block_level)(struct logfs_block *block); | ||
309 | void (*free_block)(struct super_block *sb, struct logfs_block*block); | 312 | void (*free_block)(struct super_block *sb, struct logfs_block*block); |
310 | int (*write_alias)(struct super_block *sb, | 313 | int (*write_alias)(struct super_block *sb, |
311 | struct logfs_block *block, | 314 | struct logfs_block *block, |
312 | write_alias_t *write_one_alias); | 315 | write_alias_t *write_one_alias); |
313 | }; | 316 | }; |
314 | 317 | ||
318 | #define MAX_JOURNAL_ENTRIES 256 | ||
319 | |||
315 | struct logfs_super { | 320 | struct logfs_super { |
316 | struct mtd_info *s_mtd; /* underlying device */ | 321 | struct mtd_info *s_mtd; /* underlying device */ |
317 | struct block_device *s_bdev; /* underlying device */ | 322 | struct block_device *s_bdev; /* underlying device */ |
@@ -378,7 +383,7 @@ struct logfs_super { | |||
378 | u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */ | 383 | u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */ |
379 | u64 s_last_version; | 384 | u64 s_last_version; |
380 | struct logfs_area *s_journal_area; /* open journal segment */ | 385 | struct logfs_area *s_journal_area; /* open journal segment */ |
381 | __be64 s_je_array[64]; | 386 | __be64 s_je_array[MAX_JOURNAL_ENTRIES]; |
382 | int s_no_je; | 387 | int s_no_je; |
383 | 388 | ||
384 | int s_sum_index; /* for the 12 summaries */ | 389 | int s_sum_index; /* for the 12 summaries */ |
@@ -722,4 +727,10 @@ static inline struct logfs_area *get_area(struct super_block *sb, | |||
722 | return logfs_super(sb)->s_area[(__force u8)gc_level]; | 727 | return logfs_super(sb)->s_area[(__force u8)gc_level]; |
723 | } | 728 | } |
724 | 729 | ||
730 | static inline void logfs_mempool_destroy(mempool_t *pool) | ||
731 | { | ||
732 | if (pool) | ||
733 | mempool_destroy(pool); | ||
734 | } | ||
735 | |||
725 | #endif | 736 | #endif |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index bff40253dfb2..3159db6958e5 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -430,25 +430,6 @@ static void inode_write_block(struct logfs_block *block) | |||
430 | } | 430 | } |
431 | } | 431 | } |
432 | 432 | ||
433 | static gc_level_t inode_block_level(struct logfs_block *block) | ||
434 | { | ||
435 | BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER); | ||
436 | return GC_LEVEL(LOGFS_MAX_LEVELS); | ||
437 | } | ||
438 | |||
439 | static gc_level_t indirect_block_level(struct logfs_block *block) | ||
440 | { | ||
441 | struct page *page; | ||
442 | struct inode *inode; | ||
443 | u64 bix; | ||
444 | level_t level; | ||
445 | |||
446 | page = block->page; | ||
447 | inode = page->mapping->host; | ||
448 | logfs_unpack_index(page->index, &bix, &level); | ||
449 | return expand_level(inode->i_ino, level); | ||
450 | } | ||
451 | |||
452 | /* | 433 | /* |
453 | * This silences a false, yet annoying gcc warning. I hate it when my editor | 434 | * This silences a false, yet annoying gcc warning. I hate it when my editor |
454 | * jumps into bitops.h each time I recompile this file. | 435 | * jumps into bitops.h each time I recompile this file. |
@@ -587,14 +568,12 @@ static void indirect_free_block(struct super_block *sb, | |||
587 | 568 | ||
588 | static struct logfs_block_ops inode_block_ops = { | 569 | static struct logfs_block_ops inode_block_ops = { |
589 | .write_block = inode_write_block, | 570 | .write_block = inode_write_block, |
590 | .block_level = inode_block_level, | ||
591 | .free_block = inode_free_block, | 571 | .free_block = inode_free_block, |
592 | .write_alias = inode_write_alias, | 572 | .write_alias = inode_write_alias, |
593 | }; | 573 | }; |
594 | 574 | ||
595 | struct logfs_block_ops indirect_block_ops = { | 575 | struct logfs_block_ops indirect_block_ops = { |
596 | .write_block = indirect_write_block, | 576 | .write_block = indirect_write_block, |
597 | .block_level = indirect_block_level, | ||
598 | .free_block = indirect_free_block, | 577 | .free_block = indirect_free_block, |
599 | .write_alias = indirect_write_alias, | 578 | .write_alias = indirect_write_alias, |
600 | }; | 579 | }; |
@@ -1241,6 +1220,18 @@ static void free_shadow(struct inode *inode, struct logfs_shadow *shadow) | |||
1241 | mempool_free(shadow, super->s_shadow_pool); | 1220 | mempool_free(shadow, super->s_shadow_pool); |
1242 | } | 1221 | } |
1243 | 1222 | ||
1223 | static void mark_segment(struct shadow_tree *tree, u32 segno) | ||
1224 | { | ||
1225 | int err; | ||
1226 | |||
1227 | if (!btree_lookup32(&tree->segment_map, segno)) { | ||
1228 | err = btree_insert32(&tree->segment_map, segno, (void *)1, | ||
1229 | GFP_NOFS); | ||
1230 | BUG_ON(err); | ||
1231 | tree->no_shadowed_segments++; | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1244 | /** | 1235 | /** |
1245 | * fill_shadow_tree - Propagate shadow tree changes due to a write | 1236 | * fill_shadow_tree - Propagate shadow tree changes due to a write |
1246 | * @inode: Inode owning the page | 1237 | * @inode: Inode owning the page |
@@ -1288,6 +1279,8 @@ static void fill_shadow_tree(struct inode *inode, struct page *page, | |||
1288 | 1279 | ||
1289 | super->s_dirty_used_bytes += shadow->new_len; | 1280 | super->s_dirty_used_bytes += shadow->new_len; |
1290 | super->s_dirty_free_bytes += shadow->old_len; | 1281 | super->s_dirty_free_bytes += shadow->old_len; |
1282 | mark_segment(tree, shadow->old_ofs >> super->s_segshift); | ||
1283 | mark_segment(tree, shadow->new_ofs >> super->s_segshift); | ||
1291 | } | 1284 | } |
1292 | } | 1285 | } |
1293 | 1286 | ||
@@ -1845,19 +1838,37 @@ static int __logfs_truncate(struct inode *inode, u64 size) | |||
1845 | return logfs_truncate_direct(inode, size); | 1838 | return logfs_truncate_direct(inode, size); |
1846 | } | 1839 | } |
1847 | 1840 | ||
1848 | int logfs_truncate(struct inode *inode, u64 size) | 1841 | /* |
1842 | * Truncate, by changing the segment file, can consume a fair amount | ||
1843 | * of resources. So back off from time to time and do some GC. | ||
1844 | * 8 or 2048 blocks should be well within safety limits even if | ||
1845 | * every single block resided in a different segment. | ||
1846 | */ | ||
1847 | #define TRUNCATE_STEP (8 * 1024 * 1024) | ||
1848 | int logfs_truncate(struct inode *inode, u64 target) | ||
1849 | { | 1849 | { |
1850 | struct super_block *sb = inode->i_sb; | 1850 | struct super_block *sb = inode->i_sb; |
1851 | int err; | 1851 | u64 size = i_size_read(inode); |
1852 | int err = 0; | ||
1852 | 1853 | ||
1853 | logfs_get_wblocks(sb, NULL, 1); | 1854 | size = ALIGN(size, TRUNCATE_STEP); |
1854 | err = __logfs_truncate(inode, size); | 1855 | while (size > target) { |
1855 | if (!err) | 1856 | if (size > TRUNCATE_STEP) |
1856 | err = __logfs_write_inode(inode, 0); | 1857 | size -= TRUNCATE_STEP; |
1857 | logfs_put_wblocks(sb, NULL, 1); | 1858 | else |
1859 | size = 0; | ||
1860 | if (size < target) | ||
1861 | size = target; | ||
1862 | |||
1863 | logfs_get_wblocks(sb, NULL, 1); | ||
1864 | err = __logfs_truncate(inode, target); | ||
1865 | if (!err) | ||
1866 | err = __logfs_write_inode(inode, 0); | ||
1867 | logfs_put_wblocks(sb, NULL, 1); | ||
1868 | } | ||
1858 | 1869 | ||
1859 | if (!err) | 1870 | if (!err) |
1860 | err = vmtruncate(inode, size); | 1871 | err = vmtruncate(inode, target); |
1861 | 1872 | ||
1862 | /* I don't trust error recovery yet. */ | 1873 | /* I don't trust error recovery yet. */ |
1863 | WARN_ON(err); | 1874 | WARN_ON(err); |
@@ -2251,8 +2262,6 @@ void logfs_cleanup_rw(struct super_block *sb) | |||
2251 | struct logfs_super *super = logfs_super(sb); | 2262 | struct logfs_super *super = logfs_super(sb); |
2252 | 2263 | ||
2253 | destroy_meta_inode(super->s_segfile_inode); | 2264 | destroy_meta_inode(super->s_segfile_inode); |
2254 | if (super->s_block_pool) | 2265 | logfs_mempool_destroy(super->s_block_pool); |
2255 | mempool_destroy(super->s_block_pool); | 2266 | logfs_mempool_destroy(super->s_shadow_pool); |
2256 | if (super->s_shadow_pool) | ||
2257 | mempool_destroy(super->s_shadow_pool); | ||
2258 | } | 2267 | } |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 801a3a141625..f77ce2b470ba 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
@@ -183,14 +183,8 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block, | |||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | static gc_level_t btree_block_level(struct logfs_block *block) | ||
187 | { | ||
188 | return expand_level(block->ino, block->level); | ||
189 | } | ||
190 | |||
191 | static struct logfs_block_ops btree_block_ops = { | 186 | static struct logfs_block_ops btree_block_ops = { |
192 | .write_block = btree_write_block, | 187 | .write_block = btree_write_block, |
193 | .block_level = btree_block_level, | ||
194 | .free_block = __free_block, | 188 | .free_block = __free_block, |
195 | .write_alias = btree_write_alias, | 189 | .write_alias = btree_write_alias, |
196 | }; | 190 | }; |
@@ -919,7 +913,7 @@ err: | |||
919 | for (i--; i >= 0; i--) | 913 | for (i--; i >= 0; i--) |
920 | free_area(super->s_area[i]); | 914 | free_area(super->s_area[i]); |
921 | free_area(super->s_journal_area); | 915 | free_area(super->s_journal_area); |
922 | mempool_destroy(super->s_alias_pool); | 916 | logfs_mempool_destroy(super->s_alias_pool); |
923 | return -ENOMEM; | 917 | return -ENOMEM; |
924 | } | 918 | } |
925 | 919 | ||
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index b60bfac3263c..5866ee6e1327 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "logfs.h" | 12 | #include "logfs.h" |
13 | #include <linux/bio.h> | 13 | #include <linux/bio.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/blkdev.h> | ||
15 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
16 | #include <linux/statfs.h> | 17 | #include <linux/statfs.h> |
17 | #include <linux/buffer_head.h> | 18 | #include <linux/buffer_head.h> |
@@ -137,6 +138,10 @@ static int logfs_sb_set(struct super_block *sb, void *_super) | |||
137 | sb->s_fs_info = super; | 138 | sb->s_fs_info = super; |
138 | sb->s_mtd = super->s_mtd; | 139 | sb->s_mtd = super->s_mtd; |
139 | sb->s_bdev = super->s_bdev; | 140 | sb->s_bdev = super->s_bdev; |
141 | if (sb->s_bdev) | ||
142 | sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info; | ||
143 | if (sb->s_mtd) | ||
144 | sb->s_bdi = sb->s_mtd->backing_dev_info; | ||
140 | return 0; | 145 | return 0; |
141 | } | 146 | } |
142 | 147 | ||
@@ -452,6 +457,8 @@ static int logfs_read_sb(struct super_block *sb, int read_only) | |||
452 | 457 | ||
453 | btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool); | 458 | btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool); |
454 | btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool); | 459 | btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool); |
460 | btree_init_mempool32(&super->s_shadow_tree.segment_map, | ||
461 | super->s_btree_pool); | ||
455 | 462 | ||
456 | ret = logfs_init_mapping(sb); | 463 | ret = logfs_init_mapping(sb); |
457 | if (ret) | 464 | if (ret) |
@@ -516,8 +523,8 @@ static void logfs_kill_sb(struct super_block *sb) | |||
516 | if (super->s_erase_page) | 523 | if (super->s_erase_page) |
517 | __free_page(super->s_erase_page); | 524 | __free_page(super->s_erase_page); |
518 | super->s_devops->put_device(sb); | 525 | super->s_devops->put_device(sb); |
519 | mempool_destroy(super->s_btree_pool); | 526 | logfs_mempool_destroy(super->s_btree_pool); |
520 | mempool_destroy(super->s_alias_pool); | 527 | logfs_mempool_destroy(super->s_alias_pool); |
521 | kfree(super); | 528 | kfree(super); |
522 | log_super("LogFS: Finished unmounting\n"); | 529 | log_super("LogFS: Finished unmounting\n"); |
523 | } | 530 | } |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 2a3d352c0bff..a8766c4ef2e0 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1294,7 +1294,8 @@ static int nfs4_init_server(struct nfs_server *server, | |||
1294 | 1294 | ||
1295 | /* Initialise the client representation from the mount data */ | 1295 | /* Initialise the client representation from the mount data */ |
1296 | server->flags = data->flags; | 1296 | server->flags = data->flags; |
1297 | server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR; | 1297 | server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR| |
1298 | NFS_CAP_POSIX_LOCK; | ||
1298 | server->options = data->options; | 1299 | server->options = data->options; |
1299 | 1300 | ||
1300 | /* Get a client record */ | 1301 | /* Get a client record */ |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c6f2750648f4..be46f26c9a56 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1025,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1025 | res = NULL; | 1025 | res = NULL; |
1026 | goto out; | 1026 | goto out; |
1027 | /* This turned out not to be a regular file */ | 1027 | /* This turned out not to be a regular file */ |
1028 | case -EISDIR: | ||
1028 | case -ENOTDIR: | 1029 | case -ENOTDIR: |
1029 | goto no_open; | 1030 | goto no_open; |
1030 | case -ELOOP: | 1031 | case -ELOOP: |
1031 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | 1032 | if (!(nd->intent.open.flags & O_NOFOLLOW)) |
1032 | goto no_open; | 1033 | goto no_open; |
1033 | /* case -EISDIR: */ | ||
1034 | /* case -EINVAL: */ | 1034 | /* case -EINVAL: */ |
1035 | default: | 1035 | default: |
1036 | goto out; | 1036 | goto out; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 737128f777f3..50a56edca0b5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -623,10 +623,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c | |||
623 | list_for_each_entry(pos, &nfsi->open_files, list) { | 623 | list_for_each_entry(pos, &nfsi->open_files, list) { |
624 | if (cred != NULL && pos->cred != cred) | 624 | if (cred != NULL && pos->cred != cred) |
625 | continue; | 625 | continue; |
626 | if ((pos->mode & mode) == mode) { | 626 | if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode) |
627 | ctx = get_nfs_open_context(pos); | 627 | continue; |
628 | break; | 628 | ctx = get_nfs_open_context(pos); |
629 | } | 629 | break; |
630 | } | 630 | } |
631 | spin_unlock(&inode->i_lock); | 631 | spin_unlock(&inode->i_lock); |
632 | return ctx; | 632 | return ctx; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fe0cd9eb1d4d..638067007c65 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1523,6 +1523,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
1523 | nfs_post_op_update_inode(dir, o_res->dir_attr); | 1523 | nfs_post_op_update_inode(dir, o_res->dir_attr); |
1524 | } else | 1524 | } else |
1525 | nfs_refresh_inode(dir, o_res->dir_attr); | 1525 | nfs_refresh_inode(dir, o_res->dir_attr); |
1526 | if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) | ||
1527 | server->caps &= ~NFS_CAP_POSIX_LOCK; | ||
1526 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { | 1528 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { |
1527 | status = _nfs4_proc_open_confirm(data); | 1529 | status = _nfs4_proc_open_confirm(data); |
1528 | if (status != 0) | 1530 | if (status != 0) |
@@ -1664,7 +1666,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in | |||
1664 | status = PTR_ERR(state); | 1666 | status = PTR_ERR(state); |
1665 | if (IS_ERR(state)) | 1667 | if (IS_ERR(state)) |
1666 | goto err_opendata_put; | 1668 | goto err_opendata_put; |
1667 | if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0) | 1669 | if (server->caps & NFS_CAP_POSIX_LOCK) |
1668 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); | 1670 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); |
1669 | nfs4_opendata_put(opendata); | 1671 | nfs4_opendata_put(opendata); |
1670 | nfs4_put_state_owner(sp); | 1672 | nfs4_put_state_owner(sp); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 53ff70e23993..de38d63aa920 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page) | |||
201 | struct inode *inode = page->mapping->host; | 201 | struct inode *inode = page->mapping->host; |
202 | struct nfs_server *nfss = NFS_SERVER(inode); | 202 | struct nfs_server *nfss = NFS_SERVER(inode); |
203 | 203 | ||
204 | page_cache_get(page); | ||
204 | if (atomic_long_inc_return(&nfss->writeback) > | 205 | if (atomic_long_inc_return(&nfss->writeback) > |
205 | NFS_CONGESTION_ON_THRESH) { | 206 | NFS_CONGESTION_ON_THRESH) { |
206 | set_bdi_congested(&nfss->backing_dev_info, | 207 | set_bdi_congested(&nfss->backing_dev_info, |
@@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page) | |||
216 | struct nfs_server *nfss = NFS_SERVER(inode); | 217 | struct nfs_server *nfss = NFS_SERVER(inode); |
217 | 218 | ||
218 | end_page_writeback(page); | 219 | end_page_writeback(page); |
220 | page_cache_release(page); | ||
219 | if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) | 221 | if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) |
220 | clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC); | 222 | clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC); |
221 | } | 223 | } |
@@ -421,6 +423,7 @@ static void | |||
421 | nfs_mark_request_dirty(struct nfs_page *req) | 423 | nfs_mark_request_dirty(struct nfs_page *req) |
422 | { | 424 | { |
423 | __set_page_dirty_nobuffers(req->wb_page); | 425 | __set_page_dirty_nobuffers(req->wb_page); |
426 | __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC); | ||
424 | } | 427 | } |
425 | 428 | ||
426 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 429 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
@@ -660,9 +663,11 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, | |||
660 | req = nfs_setup_write_request(ctx, page, offset, count); | 663 | req = nfs_setup_write_request(ctx, page, offset, count); |
661 | if (IS_ERR(req)) | 664 | if (IS_ERR(req)) |
662 | return PTR_ERR(req); | 665 | return PTR_ERR(req); |
666 | nfs_mark_request_dirty(req); | ||
663 | /* Update file length */ | 667 | /* Update file length */ |
664 | nfs_grow_file(page, offset, count); | 668 | nfs_grow_file(page, offset, count); |
665 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); | 669 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); |
670 | nfs_mark_request_dirty(req); | ||
666 | nfs_clear_page_tag_locked(req); | 671 | nfs_clear_page_tag_locked(req); |
667 | return 0; | 672 | return 0; |
668 | } | 673 | } |
@@ -739,8 +744,6 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
739 | status = nfs_writepage_setup(ctx, page, offset, count); | 744 | status = nfs_writepage_setup(ctx, page, offset, count); |
740 | if (status < 0) | 745 | if (status < 0) |
741 | nfs_set_pageerror(page); | 746 | nfs_set_pageerror(page); |
742 | else | ||
743 | __set_page_dirty_nobuffers(page); | ||
744 | 747 | ||
745 | dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", | 748 | dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", |
746 | status, (long long)i_size_read(inode)); | 749 | status, (long long)i_size_read(inode)); |
@@ -749,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
749 | 752 | ||
750 | static void nfs_writepage_release(struct nfs_page *req) | 753 | static void nfs_writepage_release(struct nfs_page *req) |
751 | { | 754 | { |
755 | struct page *page = req->wb_page; | ||
752 | 756 | ||
753 | if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) { | 757 | if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) |
754 | nfs_end_page_writeback(req->wb_page); | ||
755 | nfs_inode_remove_request(req); | 758 | nfs_inode_remove_request(req); |
756 | } else | ||
757 | nfs_end_page_writeback(req->wb_page); | ||
758 | nfs_clear_page_tag_locked(req); | 759 | nfs_clear_page_tag_locked(req); |
760 | nfs_end_page_writeback(page); | ||
759 | } | 761 | } |
760 | 762 | ||
761 | static int flush_task_priority(int how) | 763 | static int flush_task_priority(int how) |
@@ -779,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
779 | int how) | 781 | int how) |
780 | { | 782 | { |
781 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 783 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
782 | int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | ||
783 | int priority = flush_task_priority(how); | 784 | int priority = flush_task_priority(how); |
784 | struct rpc_task *task; | 785 | struct rpc_task *task; |
785 | struct rpc_message msg = { | 786 | struct rpc_message msg = { |
@@ -794,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
794 | .callback_ops = call_ops, | 795 | .callback_ops = call_ops, |
795 | .callback_data = data, | 796 | .callback_data = data, |
796 | .workqueue = nfsiod_workqueue, | 797 | .workqueue = nfsiod_workqueue, |
797 | .flags = flags, | 798 | .flags = RPC_TASK_ASYNC, |
798 | .priority = priority, | 799 | .priority = priority, |
799 | }; | 800 | }; |
801 | int ret = 0; | ||
800 | 802 | ||
801 | /* Set up the RPC argument and reply structs | 803 | /* Set up the RPC argument and reply structs |
802 | * NB: take care not to mess about with data->commit et al. */ | 804 | * NB: take care not to mess about with data->commit et al. */ |
@@ -835,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
835 | (unsigned long long)data->args.offset); | 837 | (unsigned long long)data->args.offset); |
836 | 838 | ||
837 | task = rpc_run_task(&task_setup_data); | 839 | task = rpc_run_task(&task_setup_data); |
838 | if (IS_ERR(task)) | 840 | if (IS_ERR(task)) { |
839 | return PTR_ERR(task); | 841 | ret = PTR_ERR(task); |
842 | goto out; | ||
843 | } | ||
844 | if (how & FLUSH_SYNC) { | ||
845 | ret = rpc_wait_for_completion_task(task); | ||
846 | if (ret == 0) | ||
847 | ret = task->tk_status; | ||
848 | } | ||
840 | rpc_put_task(task); | 849 | rpc_put_task(task); |
841 | return 0; | 850 | out: |
851 | return ret; | ||
842 | } | 852 | } |
843 | 853 | ||
844 | /* If a nfs_flush_* function fails, it should remove reqs from @head and | 854 | /* If a nfs_flush_* function fails, it should remove reqs from @head and |
@@ -847,9 +857,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
847 | */ | 857 | */ |
848 | static void nfs_redirty_request(struct nfs_page *req) | 858 | static void nfs_redirty_request(struct nfs_page *req) |
849 | { | 859 | { |
860 | struct page *page = req->wb_page; | ||
861 | |||
850 | nfs_mark_request_dirty(req); | 862 | nfs_mark_request_dirty(req); |
851 | nfs_end_page_writeback(req->wb_page); | ||
852 | nfs_clear_page_tag_locked(req); | 863 | nfs_clear_page_tag_locked(req); |
864 | nfs_end_page_writeback(page); | ||
853 | } | 865 | } |
854 | 866 | ||
855 | /* | 867 | /* |
@@ -1084,16 +1096,15 @@ static void nfs_writeback_release_full(void *calldata) | |||
1084 | if (nfs_write_need_commit(data)) { | 1096 | if (nfs_write_need_commit(data)) { |
1085 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); | 1097 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); |
1086 | nfs_mark_request_commit(req); | 1098 | nfs_mark_request_commit(req); |
1087 | nfs_end_page_writeback(page); | ||
1088 | dprintk(" marked for commit\n"); | 1099 | dprintk(" marked for commit\n"); |
1089 | goto next; | 1100 | goto next; |
1090 | } | 1101 | } |
1091 | dprintk(" OK\n"); | 1102 | dprintk(" OK\n"); |
1092 | remove_request: | 1103 | remove_request: |
1093 | nfs_end_page_writeback(page); | ||
1094 | nfs_inode_remove_request(req); | 1104 | nfs_inode_remove_request(req); |
1095 | next: | 1105 | next: |
1096 | nfs_clear_page_tag_locked(req); | 1106 | nfs_clear_page_tag_locked(req); |
1107 | nfs_end_page_writeback(page); | ||
1097 | } | 1108 | } |
1098 | nfs_writedata_release(calldata); | 1109 | nfs_writedata_release(calldata); |
1099 | } | 1110 | } |
@@ -1207,7 +1218,6 @@ static int nfs_commit_rpcsetup(struct list_head *head, | |||
1207 | { | 1218 | { |
1208 | struct nfs_page *first = nfs_list_entry(head->next); | 1219 | struct nfs_page *first = nfs_list_entry(head->next); |
1209 | struct inode *inode = first->wb_context->path.dentry->d_inode; | 1220 | struct inode *inode = first->wb_context->path.dentry->d_inode; |
1210 | int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; | ||
1211 | int priority = flush_task_priority(how); | 1221 | int priority = flush_task_priority(how); |
1212 | struct rpc_task *task; | 1222 | struct rpc_task *task; |
1213 | struct rpc_message msg = { | 1223 | struct rpc_message msg = { |
@@ -1222,7 +1232,7 @@ static int nfs_commit_rpcsetup(struct list_head *head, | |||
1222 | .callback_ops = &nfs_commit_ops, | 1232 | .callback_ops = &nfs_commit_ops, |
1223 | .callback_data = data, | 1233 | .callback_data = data, |
1224 | .workqueue = nfsiod_workqueue, | 1234 | .workqueue = nfsiod_workqueue, |
1225 | .flags = flags, | 1235 | .flags = RPC_TASK_ASYNC, |
1226 | .priority = priority, | 1236 | .priority = priority, |
1227 | }; | 1237 | }; |
1228 | 1238 | ||
@@ -1252,6 +1262,8 @@ static int nfs_commit_rpcsetup(struct list_head *head, | |||
1252 | task = rpc_run_task(&task_setup_data); | 1262 | task = rpc_run_task(&task_setup_data); |
1253 | if (IS_ERR(task)) | 1263 | if (IS_ERR(task)) |
1254 | return PTR_ERR(task); | 1264 | return PTR_ERR(task); |
1265 | if (how & FLUSH_SYNC) | ||
1266 | rpc_wait_for_completion_task(task); | ||
1255 | rpc_put_task(task); | 1267 | rpc_put_task(task); |
1256 | return 0; | 1268 | return 0; |
1257 | } | 1269 | } |
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 8d6356a804f3..7cfb87e692da 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
@@ -426,7 +426,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode, | |||
426 | bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh); | 426 | bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh); |
427 | if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), | 427 | if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), |
428 | group_offset, bitmap)) | 428 | group_offset, bitmap)) |
429 | printk(KERN_WARNING "%s: entry numer %llu already freed\n", | 429 | printk(KERN_WARNING "%s: entry number %llu already freed\n", |
430 | __func__, (unsigned long long)req->pr_entry_nr); | 430 | __func__, (unsigned long long)req->pr_entry_nr); |
431 | 431 | ||
432 | nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); | 432 | nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); |
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index 7cdd98b8d514..76c38e3e19d2 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
@@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree, | |||
1879 | struct nilfs_btree_path *path, | 1879 | struct nilfs_btree_path *path, |
1880 | int level, struct buffer_head *bh) | 1880 | int level, struct buffer_head *bh) |
1881 | { | 1881 | { |
1882 | int maxlevel, ret; | 1882 | int maxlevel = 0, ret; |
1883 | struct nilfs_btree_node *parent; | 1883 | struct nilfs_btree_node *parent; |
1884 | struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap); | 1884 | struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap); |
1885 | __u64 ptr; | 1885 | __u64 ptr; |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index c2ff1b306012..f90a33d9a5b0 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -649,7 +649,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp, | |||
649 | long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 649 | long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
650 | { | 650 | { |
651 | struct inode *inode = filp->f_dentry->d_inode; | 651 | struct inode *inode = filp->f_dentry->d_inode; |
652 | void __user *argp = (void * __user *)arg; | 652 | void __user *argp = (void __user *)arg; |
653 | 653 | ||
654 | switch (cmd) { | 654 | switch (cmd) { |
655 | case NILFS_IOCTL_CHANGE_CPMODE: | 655 | case NILFS_IOCTL_CHANGE_CPMODE: |
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig index dad7fb247ddc..3e21b1e2ad3a 100644 --- a/fs/quota/Kconfig +++ b/fs/quota/Kconfig | |||
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING | |||
33 | Note that this behavior is currently deprecated and may go away in | 33 | Note that this behavior is currently deprecated and may go away in |
34 | future. Please use notification via netlink socket instead. | 34 | future. Please use notification via netlink socket instead. |
35 | 35 | ||
36 | config QUOTA_DEBUG | ||
37 | bool "Additional quota sanity checks" | ||
38 | depends on QUOTA | ||
39 | default n | ||
40 | help | ||
41 | If you say Y here, quota subsystem will perform some additional | ||
42 | sanity checks of quota internal structures. If unsure, say N. | ||
43 | |||
36 | # Generic support for tree structured quota files. Selected when needed. | 44 | # Generic support for tree structured quota files. Selected when needed. |
37 | config QUOTA_TREE | 45 | config QUOTA_TREE |
38 | tristate | 46 | tristate |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index e0b870f4749f..788b5802a7ce 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -80,8 +80,6 @@ | |||
80 | 80 | ||
81 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
82 | 82 | ||
83 | #define __DQUOT_PARANOIA | ||
84 | |||
85 | /* | 83 | /* |
86 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas | 84 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas |
87 | * and quota formats, dqstats structure containing statistics about the lists | 85 | * and quota formats, dqstats structure containing statistics about the lists |
@@ -695,7 +693,7 @@ void dqput(struct dquot *dquot) | |||
695 | 693 | ||
696 | if (!dquot) | 694 | if (!dquot) |
697 | return; | 695 | return; |
698 | #ifdef __DQUOT_PARANOIA | 696 | #ifdef CONFIG_QUOTA_DEBUG |
699 | if (!atomic_read(&dquot->dq_count)) { | 697 | if (!atomic_read(&dquot->dq_count)) { |
700 | printk("VFS: dqput: trying to free free dquot\n"); | 698 | printk("VFS: dqput: trying to free free dquot\n"); |
701 | printk("VFS: device %s, dquot of %s %d\n", | 699 | printk("VFS: device %s, dquot of %s %d\n", |
@@ -748,7 +746,7 @@ we_slept: | |||
748 | goto we_slept; | 746 | goto we_slept; |
749 | } | 747 | } |
750 | atomic_dec(&dquot->dq_count); | 748 | atomic_dec(&dquot->dq_count); |
751 | #ifdef __DQUOT_PARANOIA | 749 | #ifdef CONFIG_QUOTA_DEBUG |
752 | /* sanity check */ | 750 | /* sanity check */ |
753 | BUG_ON(!list_empty(&dquot->dq_free)); | 751 | BUG_ON(!list_empty(&dquot->dq_free)); |
754 | #endif | 752 | #endif |
@@ -845,7 +843,7 @@ we_slept: | |||
845 | dquot = NULL; | 843 | dquot = NULL; |
846 | goto out; | 844 | goto out; |
847 | } | 845 | } |
848 | #ifdef __DQUOT_PARANOIA | 846 | #ifdef CONFIG_QUOTA_DEBUG |
849 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ | 847 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ |
850 | #endif | 848 | #endif |
851 | out: | 849 | out: |
@@ -874,14 +872,18 @@ static int dqinit_needed(struct inode *inode, int type) | |||
874 | static void add_dquot_ref(struct super_block *sb, int type) | 872 | static void add_dquot_ref(struct super_block *sb, int type) |
875 | { | 873 | { |
876 | struct inode *inode, *old_inode = NULL; | 874 | struct inode *inode, *old_inode = NULL; |
875 | #ifdef CONFIG_QUOTA_DEBUG | ||
877 | int reserved = 0; | 876 | int reserved = 0; |
877 | #endif | ||
878 | 878 | ||
879 | spin_lock(&inode_lock); | 879 | spin_lock(&inode_lock); |
880 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 880 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
881 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) | 881 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) |
882 | continue; | 882 | continue; |
883 | #ifdef CONFIG_QUOTA_DEBUG | ||
883 | if (unlikely(inode_get_rsv_space(inode) > 0)) | 884 | if (unlikely(inode_get_rsv_space(inode) > 0)) |
884 | reserved = 1; | 885 | reserved = 1; |
886 | #endif | ||
885 | if (!atomic_read(&inode->i_writecount)) | 887 | if (!atomic_read(&inode->i_writecount)) |
886 | continue; | 888 | continue; |
887 | if (!dqinit_needed(inode, type)) | 889 | if (!dqinit_needed(inode, type)) |
@@ -903,11 +905,13 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
903 | spin_unlock(&inode_lock); | 905 | spin_unlock(&inode_lock); |
904 | iput(old_inode); | 906 | iput(old_inode); |
905 | 907 | ||
908 | #ifdef CONFIG_QUOTA_DEBUG | ||
906 | if (reserved) { | 909 | if (reserved) { |
907 | printk(KERN_WARNING "VFS (%s): Writes happened before quota" | 910 | printk(KERN_WARNING "VFS (%s): Writes happened before quota" |
908 | " was turned on thus quota information is probably " | 911 | " was turned on thus quota information is probably " |
909 | "inconsistent. Please run quotacheck(8).\n", sb->s_id); | 912 | "inconsistent. Please run quotacheck(8).\n", sb->s_id); |
910 | } | 913 | } |
914 | #endif | ||
911 | } | 915 | } |
912 | 916 | ||
913 | /* | 917 | /* |
@@ -934,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, | |||
934 | inode->i_dquot[type] = NULL; | 938 | inode->i_dquot[type] = NULL; |
935 | if (dquot) { | 939 | if (dquot) { |
936 | if (dqput_blocks(dquot)) { | 940 | if (dqput_blocks(dquot)) { |
937 | #ifdef __DQUOT_PARANOIA | 941 | #ifdef CONFIG_QUOTA_DEBUG |
938 | if (atomic_read(&dquot->dq_count) != 1) | 942 | if (atomic_read(&dquot->dq_count) != 1) |
939 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); | 943 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); |
940 | #endif | 944 | #endif |
@@ -2322,34 +2326,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2322 | if (di->dqb_valid & QIF_SPACE) { | 2326 | if (di->dqb_valid & QIF_SPACE) { |
2323 | dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; | 2327 | dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; |
2324 | check_blim = 1; | 2328 | check_blim = 1; |
2325 | __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | 2329 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); |
2326 | } | 2330 | } |
2327 | if (di->dqb_valid & QIF_BLIMITS) { | 2331 | if (di->dqb_valid & QIF_BLIMITS) { |
2328 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); | 2332 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); |
2329 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); | 2333 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); |
2330 | check_blim = 1; | 2334 | check_blim = 1; |
2331 | __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | 2335 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); |
2332 | } | 2336 | } |
2333 | if (di->dqb_valid & QIF_INODES) { | 2337 | if (di->dqb_valid & QIF_INODES) { |
2334 | dm->dqb_curinodes = di->dqb_curinodes; | 2338 | dm->dqb_curinodes = di->dqb_curinodes; |
2335 | check_ilim = 1; | 2339 | check_ilim = 1; |
2336 | __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | 2340 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); |
2337 | } | 2341 | } |
2338 | if (di->dqb_valid & QIF_ILIMITS) { | 2342 | if (di->dqb_valid & QIF_ILIMITS) { |
2339 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2343 | dm->dqb_isoftlimit = di->dqb_isoftlimit; |
2340 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2344 | dm->dqb_ihardlimit = di->dqb_ihardlimit; |
2341 | check_ilim = 1; | 2345 | check_ilim = 1; |
2342 | __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | 2346 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); |
2343 | } | 2347 | } |
2344 | if (di->dqb_valid & QIF_BTIME) { | 2348 | if (di->dqb_valid & QIF_BTIME) { |
2345 | dm->dqb_btime = di->dqb_btime; | 2349 | dm->dqb_btime = di->dqb_btime; |
2346 | check_blim = 1; | 2350 | check_blim = 1; |
2347 | __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | 2351 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2348 | } | 2352 | } |
2349 | if (di->dqb_valid & QIF_ITIME) { | 2353 | if (di->dqb_valid & QIF_ITIME) { |
2350 | dm->dqb_itime = di->dqb_itime; | 2354 | dm->dqb_itime = di->dqb_itime; |
2351 | check_ilim = 1; | 2355 | check_ilim = 1; |
2352 | __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | 2356 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
2353 | } | 2357 | } |
2354 | 2358 | ||
2355 | if (check_blim) { | 2359 | if (check_blim) { |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 19626e2491c4..9a9378b4eb5a 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -125,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb, | |||
125 | 125 | ||
126 | mutex_lock(&sbi->s_alloc_mutex); | 126 | mutex_lock(&sbi->s_alloc_mutex); |
127 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; | 127 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; |
128 | if (bloc->logicalBlockNum < 0 || | 128 | if (bloc->logicalBlockNum + count < count || |
129 | (bloc->logicalBlockNum + count) > | 129 | (bloc->logicalBlockNum + count) > partmap->s_partition_len) { |
130 | partmap->s_partition_len) { | ||
131 | udf_debug("%d < %d || %d + %d > %d\n", | 130 | udf_debug("%d < %d || %d + %d > %d\n", |
132 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, | 131 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, |
133 | count, partmap->s_partition_len); | 132 | count, partmap->s_partition_len); |
@@ -393,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb, | |||
393 | 392 | ||
394 | mutex_lock(&sbi->s_alloc_mutex); | 393 | mutex_lock(&sbi->s_alloc_mutex); |
395 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; | 394 | partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; |
396 | if (bloc->logicalBlockNum < 0 || | 395 | if (bloc->logicalBlockNum + count < count || |
397 | (bloc->logicalBlockNum + count) > | 396 | (bloc->logicalBlockNum + count) > partmap->s_partition_len) { |
398 | partmap->s_partition_len) { | ||
399 | udf_debug("%d < %d || %d + %d > %d\n", | 397 | udf_debug("%d < %d || %d + %d > %d\n", |
400 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, | 398 | bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, |
401 | partmap->s_partition_len); | 399 | partmap->s_partition_len); |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 1eb06774ed90..4b6a46ccbf46 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -218,7 +218,7 @@ const struct file_operations udf_file_operations = { | |||
218 | .llseek = generic_file_llseek, | 218 | .llseek = generic_file_llseek, |
219 | }; | 219 | }; |
220 | 220 | ||
221 | static int udf_setattr(struct dentry *dentry, struct iattr *iattr) | 221 | int udf_setattr(struct dentry *dentry, struct iattr *iattr) |
222 | { | 222 | { |
223 | struct inode *inode = dentry->d_inode; | 223 | struct inode *inode = dentry->d_inode; |
224 | int error; | 224 | int error; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index bb863fe579ac..8a3fbd177cab 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1314,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1314 | break; | 1314 | break; |
1315 | case ICBTAG_FILE_TYPE_SYMLINK: | 1315 | case ICBTAG_FILE_TYPE_SYMLINK: |
1316 | inode->i_data.a_ops = &udf_symlink_aops; | 1316 | inode->i_data.a_ops = &udf_symlink_aops; |
1317 | inode->i_op = &page_symlink_inode_operations; | 1317 | inode->i_op = &udf_symlink_inode_operations; |
1318 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 1318 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
1319 | break; | 1319 | break; |
1320 | case ICBTAG_FILE_TYPE_MAIN: | 1320 | case ICBTAG_FILE_TYPE_MAIN: |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index db423ab078b1..75816025f95f 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -925,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
925 | iinfo = UDF_I(inode); | 925 | iinfo = UDF_I(inode); |
926 | inode->i_mode = S_IFLNK | S_IRWXUGO; | 926 | inode->i_mode = S_IFLNK | S_IRWXUGO; |
927 | inode->i_data.a_ops = &udf_symlink_aops; | 927 | inode->i_data.a_ops = &udf_symlink_aops; |
928 | inode->i_op = &page_symlink_inode_operations; | 928 | inode->i_op = &udf_symlink_inode_operations; |
929 | 929 | ||
930 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 930 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
931 | struct kernel_lb_addr eloc; | 931 | struct kernel_lb_addr eloc; |
@@ -1393,6 +1393,7 @@ const struct export_operations udf_export_ops = { | |||
1393 | const struct inode_operations udf_dir_inode_operations = { | 1393 | const struct inode_operations udf_dir_inode_operations = { |
1394 | .lookup = udf_lookup, | 1394 | .lookup = udf_lookup, |
1395 | .create = udf_create, | 1395 | .create = udf_create, |
1396 | .setattr = udf_setattr, | ||
1396 | .link = udf_link, | 1397 | .link = udf_link, |
1397 | .unlink = udf_unlink, | 1398 | .unlink = udf_unlink, |
1398 | .symlink = udf_symlink, | 1399 | .symlink = udf_symlink, |
@@ -1401,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = { | |||
1401 | .mknod = udf_mknod, | 1402 | .mknod = udf_mknod, |
1402 | .rename = udf_rename, | 1403 | .rename = udf_rename, |
1403 | }; | 1404 | }; |
1405 | const struct inode_operations udf_symlink_inode_operations = { | ||
1406 | .readlink = generic_readlink, | ||
1407 | .follow_link = page_follow_link_light, | ||
1408 | .put_link = page_put_link, | ||
1409 | .setattr = udf_setattr, | ||
1410 | }; | ||
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 4223ac855da9..702a1148e702 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations; | |||
76 | extern const struct file_operations udf_dir_operations; | 76 | extern const struct file_operations udf_dir_operations; |
77 | extern const struct inode_operations udf_file_inode_operations; | 77 | extern const struct inode_operations udf_file_inode_operations; |
78 | extern const struct file_operations udf_file_operations; | 78 | extern const struct file_operations udf_file_operations; |
79 | extern const struct inode_operations udf_symlink_inode_operations; | ||
79 | extern const struct address_space_operations udf_aops; | 80 | extern const struct address_space_operations udf_aops; |
80 | extern const struct address_space_operations udf_adinicb_aops; | 81 | extern const struct address_space_operations udf_adinicb_aops; |
81 | extern const struct address_space_operations udf_symlink_aops; | 82 | extern const struct address_space_operations udf_symlink_aops; |
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, | |||
131 | /* file.c */ | 132 | /* file.c */ |
132 | extern int udf_ioctl(struct inode *, struct file *, unsigned int, | 133 | extern int udf_ioctl(struct inode *, struct file *, unsigned int, |
133 | unsigned long); | 134 | unsigned long); |
134 | 135 | extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); | |
135 | /* inode.c */ | 136 | /* inode.c */ |
136 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); | 137 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |
137 | extern int udf_sync_inode(struct inode *); | 138 | extern int udf_sync_inode(struct inode *); |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 05cd85317f6f..fd9698215759 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -820,10 +820,10 @@ xfs_reclaim_inode( | |||
820 | * call into reclaim to find it in a clean state instead of waiting for | 820 | * call into reclaim to find it in a clean state instead of waiting for |
821 | * it now. We also don't return errors here - if the error is transient | 821 | * it now. We also don't return errors here - if the error is transient |
822 | * then the next reclaim pass will flush the inode, and if the error | 822 | * then the next reclaim pass will flush the inode, and if the error |
823 | * is permanent then the next sync reclaim will relcaim the inode and | 823 | * is permanent then the next sync reclaim will reclaim the inode and |
824 | * pass on the error. | 824 | * pass on the error. |
825 | */ | 825 | */ |
826 | if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) { | 826 | if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) { |
827 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, | 827 | xfs_fs_cmn_err(CE_WARN, ip->i_mount, |
828 | "inode 0x%llx background reclaim flush failed with %d", | 828 | "inode 0x%llx background reclaim flush failed with %d", |
829 | (long long)ip->i_ino, error); | 829 | (long long)ip->i_ino, error); |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index e8fba92d7cd9..2be019136287 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
745 | 745 | ||
746 | /* | 746 | /* |
747 | * Determine if we have a transaction that has gone to disk | 747 | * Determine if we have a transaction that has gone to disk |
748 | * that needs to be covered. Log activity needs to be idle (no AIL and | 748 | * that needs to be covered. To begin the transition to the idle state |
749 | * nothing in the iclogs). And, we need to be in the right state indicating | 749 | * firstly the log needs to be idle (no AIL and nothing in the iclogs). |
750 | * something has gone out. | 750 | * If we are then in a state where covering is needed, the caller is informed |
751 | * that dummy transactions are required to move the log into the idle state. | ||
752 | * | ||
753 | * Because this is called as part of the sync process, we should also indicate | ||
754 | * that dummy transactions should be issued in anything but the covered or | ||
755 | * idle states. This ensures that the log tail is accurately reflected in | ||
756 | * the log at the end of the sync, hence if a crash occurrs avoids replay | ||
757 | * of transactions where the metadata is already on disk. | ||
751 | */ | 758 | */ |
752 | int | 759 | int |
753 | xfs_log_need_covered(xfs_mount_t *mp) | 760 | xfs_log_need_covered(xfs_mount_t *mp) |
@@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
759 | return 0; | 766 | return 0; |
760 | 767 | ||
761 | spin_lock(&log->l_icloglock); | 768 | spin_lock(&log->l_icloglock); |
762 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || | 769 | switch (log->l_covered_state) { |
763 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) | 770 | case XLOG_STATE_COVER_DONE: |
764 | && !xfs_trans_ail_tail(log->l_ailp) | 771 | case XLOG_STATE_COVER_DONE2: |
765 | && xlog_iclogs_empty(log)) { | 772 | case XLOG_STATE_COVER_IDLE: |
766 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | 773 | break; |
767 | log->l_covered_state = XLOG_STATE_COVER_DONE; | 774 | case XLOG_STATE_COVER_NEED: |
768 | else { | 775 | case XLOG_STATE_COVER_NEED2: |
769 | ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2); | 776 | if (!xfs_trans_ail_tail(log->l_ailp) && |
770 | log->l_covered_state = XLOG_STATE_COVER_DONE2; | 777 | xlog_iclogs_empty(log)) { |
778 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | ||
779 | log->l_covered_state = XLOG_STATE_COVER_DONE; | ||
780 | else | ||
781 | log->l_covered_state = XLOG_STATE_COVER_DONE2; | ||
771 | } | 782 | } |
783 | /* FALLTHRU */ | ||
784 | default: | ||
772 | needed = 1; | 785 | needed = 1; |
786 | break; | ||
773 | } | 787 | } |
774 | spin_unlock(&log->l_icloglock); | 788 | spin_unlock(&log->l_icloglock); |
775 | return needed; | 789 | return needed; |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 04a6ebc27b96..2d428b088cc8 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -6,6 +6,7 @@ | |||
6 | {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ | 6 | {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ |
7 | {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 7 | {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
8 | {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 8 | {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
9 | {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
9 | {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 10 | {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
10 | {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ | 11 | {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ |
11 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ | 12 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ |
diff --git a/include/linux/ata.h b/include/linux/ata.h index b4c85e2adef5..700c5b9b3583 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -1025,8 +1025,8 @@ static inline int ata_ok(u8 status) | |||
1025 | 1025 | ||
1026 | static inline int lba_28_ok(u64 block, u32 n_block) | 1026 | static inline int lba_28_ok(u64 block, u32 n_block) |
1027 | { | 1027 | { |
1028 | /* check the ending block number */ | 1028 | /* check the ending block number: must be LESS THAN 0x0fffffff */ |
1029 | return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256); | 1029 | return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256); |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | static inline int lba_48_ok(u64 block, u32 n_block) | 1032 | static inline int lba_48_ok(u64 block, u32 n_block) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ebd22dbed861..6690e8bae7bb 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -158,7 +158,6 @@ enum rq_flag_bits { | |||
158 | struct request { | 158 | struct request { |
159 | struct list_head queuelist; | 159 | struct list_head queuelist; |
160 | struct call_single_data csd; | 160 | struct call_single_data csd; |
161 | int cpu; | ||
162 | 161 | ||
163 | struct request_queue *q; | 162 | struct request_queue *q; |
164 | 163 | ||
@@ -166,9 +165,11 @@ struct request { | |||
166 | enum rq_cmd_type_bits cmd_type; | 165 | enum rq_cmd_type_bits cmd_type; |
167 | unsigned long atomic_flags; | 166 | unsigned long atomic_flags; |
168 | 167 | ||
168 | int cpu; | ||
169 | |||
169 | /* the following two fields are internal, NEVER access directly */ | 170 | /* the following two fields are internal, NEVER access directly */ |
170 | sector_t __sector; /* sector cursor */ | ||
171 | unsigned int __data_len; /* total data len */ | 171 | unsigned int __data_len; /* total data len */ |
172 | sector_t __sector; /* sector cursor */ | ||
172 | 173 | ||
173 | struct bio *bio; | 174 | struct bio *bio; |
174 | struct bio *biotail; | 175 | struct bio *biotail; |
@@ -201,20 +202,20 @@ struct request { | |||
201 | 202 | ||
202 | unsigned short ioprio; | 203 | unsigned short ioprio; |
203 | 204 | ||
205 | int ref_count; | ||
206 | |||
204 | void *special; /* opaque pointer available for LLD use */ | 207 | void *special; /* opaque pointer available for LLD use */ |
205 | char *buffer; /* kaddr of the current segment if available */ | 208 | char *buffer; /* kaddr of the current segment if available */ |
206 | 209 | ||
207 | int tag; | 210 | int tag; |
208 | int errors; | 211 | int errors; |
209 | 212 | ||
210 | int ref_count; | ||
211 | |||
212 | /* | 213 | /* |
213 | * when request is used as a packet command carrier | 214 | * when request is used as a packet command carrier |
214 | */ | 215 | */ |
215 | unsigned short cmd_len; | ||
216 | unsigned char __cmd[BLK_MAX_CDB]; | 216 | unsigned char __cmd[BLK_MAX_CDB]; |
217 | unsigned char *cmd; | 217 | unsigned char *cmd; |
218 | unsigned short cmd_len; | ||
218 | 219 | ||
219 | unsigned int extra_len; /* length of alignment and padding */ | 220 | unsigned int extra_len; /* length of alignment and padding */ |
220 | unsigned int sense_len; | 221 | unsigned int sense_len; |
@@ -921,26 +922,7 @@ extern void blk_cleanup_queue(struct request_queue *); | |||
921 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); | 922 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); |
922 | extern void blk_queue_bounce_limit(struct request_queue *, u64); | 923 | extern void blk_queue_bounce_limit(struct request_queue *, u64); |
923 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); | 924 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); |
924 | |||
925 | /* Temporary compatibility wrapper */ | ||
926 | static inline void blk_queue_max_sectors(struct request_queue *q, unsigned int max) | ||
927 | { | ||
928 | blk_queue_max_hw_sectors(q, max); | ||
929 | } | ||
930 | |||
931 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); | 925 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); |
932 | |||
933 | static inline void blk_queue_max_phys_segments(struct request_queue *q, unsigned short max) | ||
934 | { | ||
935 | blk_queue_max_segments(q, max); | ||
936 | } | ||
937 | |||
938 | static inline void blk_queue_max_hw_segments(struct request_queue *q, unsigned short max) | ||
939 | { | ||
940 | blk_queue_max_segments(q, max); | ||
941 | } | ||
942 | |||
943 | |||
944 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); | 926 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); |
945 | extern void blk_queue_max_discard_sectors(struct request_queue *q, | 927 | extern void blk_queue_max_discard_sectors(struct request_queue *q, |
946 | unsigned int max_discard_sectors); | 928 | unsigned int max_discard_sectors); |
@@ -1030,11 +1012,6 @@ static inline int sb_issue_discard(struct super_block *sb, | |||
1030 | 1012 | ||
1031 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); | 1013 | extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); |
1032 | 1014 | ||
1033 | #define MAX_PHYS_SEGMENTS 128 | ||
1034 | #define MAX_HW_SEGMENTS 128 | ||
1035 | #define SAFE_MAX_SECTORS 255 | ||
1036 | #define MAX_SEGMENT_SIZE 65536 | ||
1037 | |||
1038 | enum blk_default_limits { | 1015 | enum blk_default_limits { |
1039 | BLK_MAX_SEGMENTS = 128, | 1016 | BLK_MAX_SEGMENTS = 128, |
1040 | BLK_SAFE_MAX_SECTORS = 255, | 1017 | BLK_SAFE_MAX_SECTORS = 255, |
diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 78962272338a..4341b1a97a34 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h | |||
@@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void); | |||
56 | #define REL_VERSION "8.3.7" | 56 | #define REL_VERSION "8.3.7" |
57 | #define API_VERSION 88 | 57 | #define API_VERSION 88 |
58 | #define PRO_VERSION_MIN 86 | 58 | #define PRO_VERSION_MIN 86 |
59 | #define PRO_VERSION_MAX 91 | 59 | #define PRO_VERSION_MAX 92 |
60 | 60 | ||
61 | 61 | ||
62 | enum drbd_io_error_p { | 62 | enum drbd_io_error_p { |
diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index a4d82f895994..f7431a4ca608 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | NL_PACKET(primary, 1, | 14 | NL_PACKET(primary, 1, |
15 | NL_BIT( 1, T_MAY_IGNORE, overwrite_peer) | 15 | NL_BIT( 1, T_MAY_IGNORE, primary_force) |
16 | ) | 16 | ) |
17 | 17 | ||
18 | NL_PACKET(secondary, 2, ) | 18 | NL_PACKET(secondary, 2, ) |
@@ -63,6 +63,7 @@ NL_PACKET(net_conf, 5, | |||
63 | NL_BIT( 41, T_MAY_IGNORE, always_asbp) | 63 | NL_BIT( 41, T_MAY_IGNORE, always_asbp) |
64 | NL_BIT( 61, T_MAY_IGNORE, no_cork) | 64 | NL_BIT( 61, T_MAY_IGNORE, no_cork) |
65 | NL_BIT( 62, T_MANDATORY, auto_sndbuf_size) | 65 | NL_BIT( 62, T_MANDATORY, auto_sndbuf_size) |
66 | NL_BIT( 70, T_MANDATORY, dry_run) | ||
66 | ) | 67 | ) |
67 | 68 | ||
68 | NL_PACKET(disconnect, 6, ) | 69 | NL_PACKET(disconnect, 6, ) |
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 40b11013408e..81f3b14d5d76 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
@@ -1,21 +1,26 @@ | |||
1 | /* | 1 | /* |
2 | * Char device interface. | 2 | * Char device interface. |
3 | * | 3 | * |
4 | * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net> | 4 | * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * it under the terms of the GNU General Public License as published by | 7 | * copy of this software and associated documentation files (the "Software"), |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * to deal in the Software without restriction, including without limitation |
9 | * (at your option) any later version. | 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 | * | 10 | * and/or sell copies of the Software, and to permit persons to whom the |
11 | * This program is distributed in the hope that it will be useful, | 11 | * Software is furnished to do so, subject to the following conditions: |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * The above copyright notice and this permission notice (including the next |
14 | * GNU General Public License for more details. | 14 | * paragraph) shall be included in all copies or substantial portions of the |
15 | * | 15 | * Software. |
16 | * You should have received a copy of the GNU General Public License | 16 | * |
17 | * along with this program; if not, write to the Free Software Foundation, | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
23 | * DEALINGS IN THE SOFTWARE. | ||
19 | */ | 24 | */ |
20 | 25 | ||
21 | #ifndef _LINUX_FIREWIRE_CDEV_H | 26 | #ifndef _LINUX_FIREWIRE_CDEV_H |
@@ -438,7 +443,7 @@ struct fw_cdev_remove_descriptor { | |||
438 | * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE | 443 | * @type: %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE |
439 | * @header_size: Header size to strip for receive contexts | 444 | * @header_size: Header size to strip for receive contexts |
440 | * @channel: Channel to bind to | 445 | * @channel: Channel to bind to |
441 | * @speed: Speed to transmit at | 446 | * @speed: Speed for transmit contexts |
442 | * @closure: To be returned in &fw_cdev_event_iso_interrupt | 447 | * @closure: To be returned in &fw_cdev_event_iso_interrupt |
443 | * @handle: Handle to context, written back by kernel | 448 | * @handle: Handle to context, written back by kernel |
444 | * | 449 | * |
@@ -451,6 +456,9 @@ struct fw_cdev_remove_descriptor { | |||
451 | * If a context was successfully created, the kernel writes back a handle to the | 456 | * If a context was successfully created, the kernel writes back a handle to the |
452 | * context, which must be passed in for subsequent operations on that context. | 457 | * context, which must be passed in for subsequent operations on that context. |
453 | * | 458 | * |
459 | * For receive contexts, @header_size must be at least 4 and must be a multiple | ||
460 | * of 4. | ||
461 | * | ||
454 | * Note that the effect of a @header_size > 4 depends on | 462 | * Note that the effect of a @header_size > 4 depends on |
455 | * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt. | 463 | * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt. |
456 | */ | 464 | */ |
@@ -481,10 +489,34 @@ struct fw_cdev_create_iso_context { | |||
481 | * | 489 | * |
482 | * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. | 490 | * &struct fw_cdev_iso_packet is used to describe isochronous packet queues. |
483 | * | 491 | * |
484 | * Use the FW_CDEV_ISO_ macros to fill in @control. The sy and tag fields are | 492 | * Use the FW_CDEV_ISO_ macros to fill in @control. |
485 | * specified by IEEE 1394a and IEC 61883. | 493 | * |
486 | * | 494 | * For transmit packets, the header length must be a multiple of 4 and specifies |
487 | * FIXME - finish this documentation | 495 | * the numbers of bytes in @header that will be prepended to the packet's |
496 | * payload; these bytes are copied into the kernel and will not be accessed | ||
497 | * after the ioctl has returned. The sy and tag fields are copied to the iso | ||
498 | * packet header (these fields are specified by IEEE 1394a and IEC 61883-1). | ||
499 | * The skip flag specifies that no packet is to be sent in a frame; when using | ||
500 | * this, all other fields except the interrupt flag must be zero. | ||
501 | * | ||
502 | * For receive packets, the header length must be a multiple of the context's | ||
503 | * header size; if the header length is larger than the context's header size, | ||
504 | * multiple packets are queued for this entry. The sy and tag fields are | ||
505 | * ignored. If the sync flag is set, the context drops all packets until | ||
506 | * a packet with a matching sy field is received (the sync value to wait for is | ||
507 | * specified in the &fw_cdev_start_iso structure). The payload length defines | ||
508 | * how many payload bytes can be received for one packet (in addition to payload | ||
509 | * quadlets that have been defined as headers and are stripped and returned in | ||
510 | * the &fw_cdev_event_iso_interrupt structure). If more bytes are received, the | ||
511 | * additional bytes are dropped. If less bytes are received, the remaining | ||
512 | * bytes in this part of the payload buffer will not be written to, not even by | ||
513 | * the next packet, i.e., packets received in consecutive frames will not | ||
514 | * necessarily be consecutive in memory. If an entry has queued multiple | ||
515 | * packets, the payload length is divided equally among them. | ||
516 | * | ||
517 | * When a packet with the interrupt flag set has been completed, the | ||
518 | * &fw_cdev_event_iso_interrupt event will be sent. An entry that has queued | ||
519 | * multiple receive packets is completed when its last packet is completed. | ||
488 | */ | 520 | */ |
489 | struct fw_cdev_iso_packet { | 521 | struct fw_cdev_iso_packet { |
490 | __u32 control; | 522 | __u32 control; |
@@ -501,7 +533,7 @@ struct fw_cdev_iso_packet { | |||
501 | * Queue a number of isochronous packets for reception or transmission. | 533 | * Queue a number of isochronous packets for reception or transmission. |
502 | * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, | 534 | * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs, |
503 | * which describe how to transmit from or receive into a contiguous region | 535 | * which describe how to transmit from or receive into a contiguous region |
504 | * of a mmap()'ed payload buffer. As part of the packet descriptors, | 536 | * of a mmap()'ed payload buffer. As part of transmit packet descriptors, |
505 | * a series of headers can be supplied, which will be prepended to the | 537 | * a series of headers can be supplied, which will be prepended to the |
506 | * payload during DMA. | 538 | * payload during DMA. |
507 | * | 539 | * |
@@ -620,8 +652,8 @@ struct fw_cdev_get_cycle_timer2 { | |||
620 | * instead of allocated. | 652 | * instead of allocated. |
621 | * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation. | 653 | * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation. |
622 | * | 654 | * |
623 | * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources | 655 | * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources |
624 | * for the lifetime of the fd or handle. | 656 | * for the lifetime of the fd or @handle. |
625 | * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources | 657 | * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources |
626 | * for the duration of a bus generation. | 658 | * for the duration of a bus generation. |
627 | * | 659 | * |
diff --git a/include/linux/firewire-constants.h b/include/linux/firewire-constants.h index b316770a43fd..9c63f06e67f2 100644 --- a/include/linux/firewire-constants.h +++ b/include/linux/firewire-constants.h | |||
@@ -1,3 +1,28 @@ | |||
1 | /* | ||
2 | * IEEE 1394 constants. | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net> | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the next | ||
14 | * paragraph) shall be included in all copies or substantial portions of the | ||
15 | * Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
23 | * DEALINGS IN THE SOFTWARE. | ||
24 | */ | ||
25 | |||
1 | #ifndef _LINUX_FIREWIRE_CONSTANTS_H | 26 | #ifndef _LINUX_FIREWIRE_CONSTANTS_H |
2 | #define _LINUX_FIREWIRE_CONSTANTS_H | 27 | #define _LINUX_FIREWIRE_CONSTANTS_H |
3 | 28 | ||
@@ -21,7 +46,7 @@ | |||
21 | #define EXTCODE_WRAP_ADD 0x6 | 46 | #define EXTCODE_WRAP_ADD 0x6 |
22 | #define EXTCODE_VENDOR_DEPENDENT 0x7 | 47 | #define EXTCODE_VENDOR_DEPENDENT 0x7 |
23 | 48 | ||
24 | /* Juju specific tcodes */ | 49 | /* Linux firewire-core (Juju) specific tcodes */ |
25 | #define TCODE_LOCK_MASK_SWAP (0x10 | EXTCODE_MASK_SWAP) | 50 | #define TCODE_LOCK_MASK_SWAP (0x10 | EXTCODE_MASK_SWAP) |
26 | #define TCODE_LOCK_COMPARE_SWAP (0x10 | EXTCODE_COMPARE_SWAP) | 51 | #define TCODE_LOCK_COMPARE_SWAP (0x10 | EXTCODE_COMPARE_SWAP) |
27 | #define TCODE_LOCK_FETCH_ADD (0x10 | EXTCODE_FETCH_ADD) | 52 | #define TCODE_LOCK_FETCH_ADD (0x10 | EXTCODE_FETCH_ADD) |
@@ -36,7 +61,7 @@ | |||
36 | #define RCODE_TYPE_ERROR 0x6 | 61 | #define RCODE_TYPE_ERROR 0x6 |
37 | #define RCODE_ADDRESS_ERROR 0x7 | 62 | #define RCODE_ADDRESS_ERROR 0x7 |
38 | 63 | ||
39 | /* Juju specific rcodes */ | 64 | /* Linux firewire-core (Juju) specific rcodes */ |
40 | #define RCODE_SEND_ERROR 0x10 | 65 | #define RCODE_SEND_ERROR 0x10 |
41 | #define RCODE_CANCELLED 0x11 | 66 | #define RCODE_CANCELLED 0x11 |
42 | #define RCODE_BUSY 0x12 | 67 | #define RCODE_BUSY 0x12 |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 56b50514ab25..5f2f4c4d8fb0 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
@@ -109,7 +109,7 @@ struct hd_struct { | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | #define GENHD_FL_REMOVABLE 1 | 111 | #define GENHD_FL_REMOVABLE 1 |
112 | #define GENHD_FL_DRIVERFS 2 | 112 | /* 2 is unused */ |
113 | #define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 | 113 | #define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 |
114 | #define GENHD_FL_CD 8 | 114 | #define GENHD_FL_CD 8 |
115 | #define GENHD_FL_UP 16 | 115 | #define GENHD_FL_UP 16 |
diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 87018dc5527d..9e7a12d6385d 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h | |||
@@ -782,7 +782,6 @@ extern int i2o_exec_lct_get(struct i2o_controller *); | |||
782 | #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) | 782 | #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) |
783 | #define to_i2o_device(dev) container_of(dev, struct i2o_device, device) | 783 | #define to_i2o_device(dev) container_of(dev, struct i2o_device, device) |
784 | #define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device) | 784 | #define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device) |
785 | #define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj)) | ||
786 | 785 | ||
787 | /** | 786 | /** |
788 | * i2o_out_to_virt - Turn an I2O message to a virtual address | 787 | * i2o_out_to_virt - Turn an I2O message to a virtual address |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 97e6ab435184..3239d1c10acb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1169,6 +1169,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); | |||
1169 | extern void ide_timer_expiry(unsigned long); | 1169 | extern void ide_timer_expiry(unsigned long); |
1170 | extern irqreturn_t ide_intr(int irq, void *dev_id); | 1170 | extern irqreturn_t ide_intr(int irq, void *dev_id); |
1171 | extern void do_ide_request(struct request_queue *); | 1171 | extern void do_ide_request(struct request_queue *); |
1172 | extern void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq); | ||
1172 | 1173 | ||
1173 | void ide_init_disk(struct gendisk *, ide_drive_t *); | 1174 | void ide_init_disk(struct gendisk *, ide_drive_t *); |
1174 | 1175 | ||
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 3bd018baae20..c964cd7f436a 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h | |||
@@ -44,6 +44,7 @@ struct matrix_keymap_data { | |||
44 | * @active_low: gpio polarity | 44 | * @active_low: gpio polarity |
45 | * @wakeup: controls whether the device should be set up as wakeup | 45 | * @wakeup: controls whether the device should be set up as wakeup |
46 | * source | 46 | * source |
47 | * @no_autorepeat: disable key autorepeat | ||
47 | * | 48 | * |
48 | * This structure represents platform-specific data that use used by | 49 | * This structure represents platform-specific data that use used by |
49 | * matrix_keypad driver to perform proper initialization. | 50 | * matrix_keypad driver to perform proper initialization. |
@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data { | |||
64 | 65 | ||
65 | bool active_low; | 66 | bool active_low; |
66 | bool wakeup; | 67 | bool wakeup; |
68 | bool no_autorepeat; | ||
67 | }; | 69 | }; |
68 | 70 | ||
69 | /** | 71 | /** |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 60df9c84ecae..23ea02253900 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -160,6 +160,7 @@ struct kvm_pit_config { | |||
160 | #define KVM_EXIT_DCR 15 | 160 | #define KVM_EXIT_DCR 15 |
161 | #define KVM_EXIT_NMI 16 | 161 | #define KVM_EXIT_NMI 16 |
162 | #define KVM_EXIT_INTERNAL_ERROR 17 | 162 | #define KVM_EXIT_INTERNAL_ERROR 17 |
163 | #define KVM_EXIT_OSI 18 | ||
163 | 164 | ||
164 | /* For KVM_EXIT_INTERNAL_ERROR */ | 165 | /* For KVM_EXIT_INTERNAL_ERROR */ |
165 | #define KVM_INTERNAL_ERROR_EMULATION 1 | 166 | #define KVM_INTERNAL_ERROR_EMULATION 1 |
@@ -259,6 +260,10 @@ struct kvm_run { | |||
259 | __u32 ndata; | 260 | __u32 ndata; |
260 | __u64 data[16]; | 261 | __u64 data[16]; |
261 | } internal; | 262 | } internal; |
263 | /* KVM_EXIT_OSI */ | ||
264 | struct { | ||
265 | __u64 gprs[32]; | ||
266 | } osi; | ||
262 | /* Fix the size of the union. */ | 267 | /* Fix the size of the union. */ |
263 | char padding[256]; | 268 | char padding[256]; |
264 | }; | 269 | }; |
@@ -400,6 +405,15 @@ struct kvm_ioeventfd { | |||
400 | __u8 pad[36]; | 405 | __u8 pad[36]; |
401 | }; | 406 | }; |
402 | 407 | ||
408 | /* for KVM_ENABLE_CAP */ | ||
409 | struct kvm_enable_cap { | ||
410 | /* in */ | ||
411 | __u32 cap; | ||
412 | __u32 flags; | ||
413 | __u64 args[4]; | ||
414 | __u8 pad[64]; | ||
415 | }; | ||
416 | |||
403 | #define KVMIO 0xAE | 417 | #define KVMIO 0xAE |
404 | 418 | ||
405 | /* | 419 | /* |
@@ -501,7 +515,15 @@ struct kvm_ioeventfd { | |||
501 | #define KVM_CAP_HYPERV_VAPIC 45 | 515 | #define KVM_CAP_HYPERV_VAPIC 45 |
502 | #define KVM_CAP_HYPERV_SPIN 46 | 516 | #define KVM_CAP_HYPERV_SPIN 46 |
503 | #define KVM_CAP_PCI_SEGMENT 47 | 517 | #define KVM_CAP_PCI_SEGMENT 47 |
518 | #define KVM_CAP_PPC_PAIRED_SINGLES 48 | ||
519 | #define KVM_CAP_INTR_SHADOW 49 | ||
520 | #ifdef __KVM_HAVE_DEBUGREGS | ||
521 | #define KVM_CAP_DEBUGREGS 50 | ||
522 | #endif | ||
504 | #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 | 523 | #define KVM_CAP_X86_ROBUST_SINGLESTEP 51 |
524 | #define KVM_CAP_PPC_OSI 52 | ||
525 | #define KVM_CAP_PPC_UNSET_IRQ 53 | ||
526 | #define KVM_CAP_ENABLE_CAP 54 | ||
505 | 527 | ||
506 | #ifdef KVM_CAP_IRQ_ROUTING | 528 | #ifdef KVM_CAP_IRQ_ROUTING |
507 | 529 | ||
@@ -688,6 +710,10 @@ struct kvm_clock_data { | |||
688 | /* Available with KVM_CAP_VCPU_EVENTS */ | 710 | /* Available with KVM_CAP_VCPU_EVENTS */ |
689 | #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) | 711 | #define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) |
690 | #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) | 712 | #define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) |
713 | /* Available with KVM_CAP_DEBUGREGS */ | ||
714 | #define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) | ||
715 | #define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) | ||
716 | #define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) | ||
691 | 717 | ||
692 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) | 718 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) |
693 | 719 | ||
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a3fd0f91d943..55830638aeb1 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -54,7 +54,7 @@ extern struct kmem_cache *kvm_vcpu_cache; | |||
54 | */ | 54 | */ |
55 | struct kvm_io_bus { | 55 | struct kvm_io_bus { |
56 | int dev_count; | 56 | int dev_count; |
57 | #define NR_IOBUS_DEVS 6 | 57 | #define NR_IOBUS_DEVS 200 |
58 | struct kvm_io_device *devs[NR_IOBUS_DEVS]; | 58 | struct kvm_io_device *devs[NR_IOBUS_DEVS]; |
59 | }; | 59 | }; |
60 | 60 | ||
@@ -105,6 +105,12 @@ struct kvm_vcpu { | |||
105 | struct kvm_vcpu_arch arch; | 105 | struct kvm_vcpu_arch arch; |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* | ||
109 | * Some of the bitops functions do not support too long bitmaps. | ||
110 | * This number must be determined not to exceed such limits. | ||
111 | */ | ||
112 | #define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1) | ||
113 | |||
108 | struct kvm_memory_slot { | 114 | struct kvm_memory_slot { |
109 | gfn_t base_gfn; | 115 | gfn_t base_gfn; |
110 | unsigned long npages; | 116 | unsigned long npages; |
@@ -119,6 +125,11 @@ struct kvm_memory_slot { | |||
119 | int user_alloc; | 125 | int user_alloc; |
120 | }; | 126 | }; |
121 | 127 | ||
128 | static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot) | ||
129 | { | ||
130 | return ALIGN(memslot->npages, BITS_PER_LONG) / 8; | ||
131 | } | ||
132 | |||
122 | struct kvm_kernel_irq_routing_entry { | 133 | struct kvm_kernel_irq_routing_entry { |
123 | u32 gsi; | 134 | u32 gsi; |
124 | u32 type; | 135 | u32 type; |
diff --git a/include/linux/lcm.h b/include/linux/lcm.h new file mode 100644 index 000000000000..7bf01d779b45 --- /dev/null +++ b/include/linux/lcm.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _LCM_H | ||
2 | #define _LCM_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | |||
6 | unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__; | ||
7 | |||
8 | #endif /* _LCM_H */ | ||
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 717a5e54eb1d..e82957acea56 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -176,6 +176,7 @@ struct nfs_server { | |||
176 | #define NFS_CAP_ATIME (1U << 11) | 176 | #define NFS_CAP_ATIME (1U << 11) |
177 | #define NFS_CAP_CTIME (1U << 12) | 177 | #define NFS_CAP_CTIME (1U << 12) |
178 | #define NFS_CAP_MTIME (1U << 13) | 178 | #define NFS_CAP_MTIME (1U << 13) |
179 | #define NFS_CAP_POSIX_LOCK (1U << 14) | ||
179 | 180 | ||
180 | 181 | ||
181 | /* maximum number of slots to use */ | 182 | /* maximum number of slots to use */ |
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index c5da74918096..55ca73cf25e5 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h | |||
@@ -121,6 +121,13 @@ do { \ | |||
121 | * (Note, rcu_assign_pointer and rcu_dereference are not needed to control | 121 | * (Note, rcu_assign_pointer and rcu_dereference are not needed to control |
122 | * access to data items when inserting into or looking up from the radix tree) | 122 | * access to data items when inserting into or looking up from the radix tree) |
123 | * | 123 | * |
124 | * Note that the value returned by radix_tree_tag_get() may not be relied upon | ||
125 | * if only the RCU read lock is held. Functions to set/clear tags and to | ||
126 | * delete nodes running concurrently with it may affect its result such that | ||
127 | * two consecutive reads in the same locked section may return different | ||
128 | * values. If reliability is required, modification functions must also be | ||
129 | * excluded from concurrency. | ||
130 | * | ||
124 | * radix_tree_tagged is able to be called without locking or RCU. | 131 | * radix_tree_tagged is able to be called without locking or RCU. |
125 | */ | 132 | */ |
126 | 133 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 872a98e13d6a..07db2feb8572 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -101,10 +101,7 @@ extern struct lockdep_map rcu_sched_lock_map; | |||
101 | # define rcu_read_release_sched() \ | 101 | # define rcu_read_release_sched() \ |
102 | lock_release(&rcu_sched_lock_map, 1, _THIS_IP_) | 102 | lock_release(&rcu_sched_lock_map, 1, _THIS_IP_) |
103 | 103 | ||
104 | static inline int debug_lockdep_rcu_enabled(void) | 104 | extern int debug_lockdep_rcu_enabled(void); |
105 | { | ||
106 | return likely(rcu_scheduler_active && debug_locks); | ||
107 | } | ||
108 | 105 | ||
109 | /** | 106 | /** |
110 | * rcu_read_lock_held - might we be in RCU read-side critical section? | 107 | * rcu_read_lock_held - might we be in RCU read-side critical section? |
@@ -195,12 +192,30 @@ static inline int rcu_read_lock_sched_held(void) | |||
195 | 192 | ||
196 | /** | 193 | /** |
197 | * rcu_dereference_check - rcu_dereference with debug checking | 194 | * rcu_dereference_check - rcu_dereference with debug checking |
195 | * @p: The pointer to read, prior to dereferencing | ||
196 | * @c: The conditions under which the dereference will take place | ||
197 | * | ||
198 | * Do an rcu_dereference(), but check that the conditions under which the | ||
199 | * dereference will take place are correct. Typically the conditions indicate | ||
200 | * the various locking conditions that should be held at that point. The check | ||
201 | * should return true if the conditions are satisfied. | ||
202 | * | ||
203 | * For example: | ||
204 | * | ||
205 | * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() || | ||
206 | * lockdep_is_held(&foo->lock)); | ||
198 | * | 207 | * |
199 | * Do an rcu_dereference(), but check that the context is correct. | 208 | * could be used to indicate to lockdep that foo->bar may only be dereferenced |
200 | * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to | 209 | * if either the RCU read lock is held, or that the lock required to replace |
201 | * ensure that the rcu_dereference_check() executes within an RCU | 210 | * the bar struct at foo->bar is held. |
202 | * read-side critical section. It is also possible to check for | 211 | * |
203 | * locks being held, for example, by using lockdep_is_held(). | 212 | * Note that the list of conditions may also include indications of when a lock |
213 | * need not be held, for example during initialisation or destruction of the | ||
214 | * target struct: | ||
215 | * | ||
216 | * bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() || | ||
217 | * lockdep_is_held(&foo->lock) || | ||
218 | * atomic_read(&foo->usage) == 0); | ||
204 | */ | 219 | */ |
205 | #define rcu_dereference_check(p, c) \ | 220 | #define rcu_dereference_check(p, c) \ |
206 | ({ \ | 221 | ({ \ |
@@ -209,13 +224,45 @@ static inline int rcu_read_lock_sched_held(void) | |||
209 | rcu_dereference_raw(p); \ | 224 | rcu_dereference_raw(p); \ |
210 | }) | 225 | }) |
211 | 226 | ||
227 | /** | ||
228 | * rcu_dereference_protected - fetch RCU pointer when updates prevented | ||
229 | * | ||
230 | * Return the value of the specified RCU-protected pointer, but omit | ||
231 | * both the smp_read_barrier_depends() and the ACCESS_ONCE(). This | ||
232 | * is useful in cases where update-side locks prevent the value of the | ||
233 | * pointer from changing. Please note that this primitive does -not- | ||
234 | * prevent the compiler from repeating this reference or combining it | ||
235 | * with other references, so it should not be used without protection | ||
236 | * of appropriate locks. | ||
237 | */ | ||
238 | #define rcu_dereference_protected(p, c) \ | ||
239 | ({ \ | ||
240 | if (debug_lockdep_rcu_enabled() && !(c)) \ | ||
241 | lockdep_rcu_dereference(__FILE__, __LINE__); \ | ||
242 | (p); \ | ||
243 | }) | ||
244 | |||
212 | #else /* #ifdef CONFIG_PROVE_RCU */ | 245 | #else /* #ifdef CONFIG_PROVE_RCU */ |
213 | 246 | ||
214 | #define rcu_dereference_check(p, c) rcu_dereference_raw(p) | 247 | #define rcu_dereference_check(p, c) rcu_dereference_raw(p) |
248 | #define rcu_dereference_protected(p, c) (p) | ||
215 | 249 | ||
216 | #endif /* #else #ifdef CONFIG_PROVE_RCU */ | 250 | #endif /* #else #ifdef CONFIG_PROVE_RCU */ |
217 | 251 | ||
218 | /** | 252 | /** |
253 | * rcu_access_pointer - fetch RCU pointer with no dereferencing | ||
254 | * | ||
255 | * Return the value of the specified RCU-protected pointer, but omit the | ||
256 | * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful | ||
257 | * when the value of this pointer is accessed, but the pointer is not | ||
258 | * dereferenced, for example, when testing an RCU-protected pointer against | ||
259 | * NULL. This may also be used in cases where update-side locks prevent | ||
260 | * the value of the pointer from changing, but rcu_dereference_protected() | ||
261 | * is a lighter-weight primitive for this use case. | ||
262 | */ | ||
263 | #define rcu_access_pointer(p) ACCESS_ONCE(p) | ||
264 | |||
265 | /** | ||
219 | * rcu_read_lock - mark the beginning of an RCU read-side critical section. | 266 | * rcu_read_lock - mark the beginning of an RCU read-side critical section. |
220 | * | 267 | * |
221 | * When synchronize_rcu() is invoked on one CPU while other CPUs | 268 | * When synchronize_rcu() is invoked on one CPU while other CPUs |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 28c9fd020d39..ebd747265294 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -183,9 +183,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev, | |||
183 | { | 183 | { |
184 | /* Nothing except the stubbed out regulator API should be | 184 | /* Nothing except the stubbed out regulator API should be |
185 | * looking at the value except to check if it is an error | 185 | * looking at the value except to check if it is an error |
186 | * value so the actual return value doesn't matter. | 186 | * value. Drivers are free to handle NULL specifically by |
187 | * skipping all regulator API calls, but they don't have to. | ||
188 | * Drivers which don't, should make sure they properly handle | ||
189 | * corner cases of the API, such as regulator_get_voltage() | ||
190 | * returning 0. | ||
187 | */ | 191 | */ |
188 | return (struct regulator *)id; | 192 | return NULL; |
189 | } | 193 | } |
190 | static inline void regulator_put(struct regulator *regulator) | 194 | static inline void regulator_put(struct regulator *regulator) |
191 | { | 195 | { |
diff --git a/include/linux/slab.h b/include/linux/slab.h index 488446289cab..49d1247cd6d9 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h | |||
@@ -106,6 +106,7 @@ int kmem_cache_shrink(struct kmem_cache *); | |||
106 | void kmem_cache_free(struct kmem_cache *, void *); | 106 | void kmem_cache_free(struct kmem_cache *, void *); |
107 | unsigned int kmem_cache_size(struct kmem_cache *); | 107 | unsigned int kmem_cache_size(struct kmem_cache *); |
108 | const char *kmem_cache_name(struct kmem_cache *); | 108 | const char *kmem_cache_name(struct kmem_cache *); |
109 | int kern_ptr_validate(const void *ptr, unsigned long size); | ||
109 | int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); | 110 | int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); |
110 | 111 | ||
111 | /* | 112 | /* |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 76e8903cd204..36520ded3e06 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -34,6 +34,9 @@ struct writeback_control { | |||
34 | enum writeback_sync_modes sync_mode; | 34 | enum writeback_sync_modes sync_mode; |
35 | unsigned long *older_than_this; /* If !NULL, only write back inodes | 35 | unsigned long *older_than_this; /* If !NULL, only write back inodes |
36 | older than this */ | 36 | older than this */ |
37 | unsigned long wb_start; /* Time writeback_inodes_wb was | ||
38 | called. This is needed to avoid | ||
39 | extra jobs and livelock */ | ||
37 | long nr_to_write; /* Write this many pages, and decrement | 40 | long nr_to_write; /* Write this many pages, and decrement |
38 | this for each page written */ | 41 | this for each page written */ |
39 | long pages_skipped; /* Pages which were not written */ | 42 | long pages_skipped; /* Pages which were not written */ |
diff --git a/include/net/x25.h b/include/net/x25.h index 15ef9624ab75..468551ea4f1d 100644 --- a/include/net/x25.h +++ b/include/net/x25.h | |||
@@ -183,6 +183,10 @@ extern int sysctl_x25_clear_request_timeout; | |||
183 | extern int sysctl_x25_ack_holdback_timeout; | 183 | extern int sysctl_x25_ack_holdback_timeout; |
184 | extern int sysctl_x25_forward; | 184 | extern int sysctl_x25_forward; |
185 | 185 | ||
186 | extern int x25_parse_address_block(struct sk_buff *skb, | ||
187 | struct x25_address *called_addr, | ||
188 | struct x25_address *calling_addr); | ||
189 | |||
186 | extern int x25_addr_ntoa(unsigned char *, struct x25_address *, | 190 | extern int x25_addr_ntoa(unsigned char *, struct x25_address *, |
187 | struct x25_address *); | 191 | struct x25_address *); |
188 | extern int x25_addr_aton(unsigned char *, struct x25_address *, | 192 | extern int x25_addr_aton(unsigned char *, struct x25_address *, |
diff --git a/include/trace/events/block.h b/include/trace/events/block.h index 5fb72733331e..d870a918559c 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h | |||
@@ -40,6 +40,16 @@ DECLARE_EVENT_CLASS(block_rq_with_error, | |||
40 | __entry->nr_sector, __entry->errors) | 40 | __entry->nr_sector, __entry->errors) |
41 | ); | 41 | ); |
42 | 42 | ||
43 | /** | ||
44 | * block_rq_abort - abort block operation request | ||
45 | * @q: queue containing the block operation request | ||
46 | * @rq: block IO operation request | ||
47 | * | ||
48 | * Called immediately after pending block IO operation request @rq in | ||
49 | * queue @q is aborted. The fields in the operation request @rq | ||
50 | * can be examined to determine which device and sectors the pending | ||
51 | * operation would access. | ||
52 | */ | ||
43 | DEFINE_EVENT(block_rq_with_error, block_rq_abort, | 53 | DEFINE_EVENT(block_rq_with_error, block_rq_abort, |
44 | 54 | ||
45 | TP_PROTO(struct request_queue *q, struct request *rq), | 55 | TP_PROTO(struct request_queue *q, struct request *rq), |
@@ -47,6 +57,15 @@ DEFINE_EVENT(block_rq_with_error, block_rq_abort, | |||
47 | TP_ARGS(q, rq) | 57 | TP_ARGS(q, rq) |
48 | ); | 58 | ); |
49 | 59 | ||
60 | /** | ||
61 | * block_rq_requeue - place block IO request back on a queue | ||
62 | * @q: queue holding operation | ||
63 | * @rq: block IO operation request | ||
64 | * | ||
65 | * The block operation request @rq is being placed back into queue | ||
66 | * @q. For some reason the request was not completed and needs to be | ||
67 | * put back in the queue. | ||
68 | */ | ||
50 | DEFINE_EVENT(block_rq_with_error, block_rq_requeue, | 69 | DEFINE_EVENT(block_rq_with_error, block_rq_requeue, |
51 | 70 | ||
52 | TP_PROTO(struct request_queue *q, struct request *rq), | 71 | TP_PROTO(struct request_queue *q, struct request *rq), |
@@ -54,6 +73,17 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue, | |||
54 | TP_ARGS(q, rq) | 73 | TP_ARGS(q, rq) |
55 | ); | 74 | ); |
56 | 75 | ||
76 | /** | ||
77 | * block_rq_complete - block IO operation completed by device driver | ||
78 | * @q: queue containing the block operation request | ||
79 | * @rq: block operations request | ||
80 | * | ||
81 | * The block_rq_complete tracepoint event indicates that some portion | ||
82 | * of operation request has been completed by the device driver. If | ||
83 | * the @rq->bio is %NULL, then there is absolutely no additional work to | ||
84 | * do for the request. If @rq->bio is non-NULL then there is | ||
85 | * additional work required to complete the request. | ||
86 | */ | ||
57 | DEFINE_EVENT(block_rq_with_error, block_rq_complete, | 87 | DEFINE_EVENT(block_rq_with_error, block_rq_complete, |
58 | 88 | ||
59 | TP_PROTO(struct request_queue *q, struct request *rq), | 89 | TP_PROTO(struct request_queue *q, struct request *rq), |
@@ -95,6 +125,16 @@ DECLARE_EVENT_CLASS(block_rq, | |||
95 | __entry->nr_sector, __entry->comm) | 125 | __entry->nr_sector, __entry->comm) |
96 | ); | 126 | ); |
97 | 127 | ||
128 | /** | ||
129 | * block_rq_insert - insert block operation request into queue | ||
130 | * @q: target queue | ||
131 | * @rq: block IO operation request | ||
132 | * | ||
133 | * Called immediately before block operation request @rq is inserted | ||
134 | * into queue @q. The fields in the operation request @rq struct can | ||
135 | * be examined to determine which device and sectors the pending | ||
136 | * operation would access. | ||
137 | */ | ||
98 | DEFINE_EVENT(block_rq, block_rq_insert, | 138 | DEFINE_EVENT(block_rq, block_rq_insert, |
99 | 139 | ||
100 | TP_PROTO(struct request_queue *q, struct request *rq), | 140 | TP_PROTO(struct request_queue *q, struct request *rq), |
@@ -102,6 +142,14 @@ DEFINE_EVENT(block_rq, block_rq_insert, | |||
102 | TP_ARGS(q, rq) | 142 | TP_ARGS(q, rq) |
103 | ); | 143 | ); |
104 | 144 | ||
145 | /** | ||
146 | * block_rq_issue - issue pending block IO request operation to device driver | ||
147 | * @q: queue holding operation | ||
148 | * @rq: block IO operation operation request | ||
149 | * | ||
150 | * Called when block operation request @rq from queue @q is sent to a | ||
151 | * device driver for processing. | ||
152 | */ | ||
105 | DEFINE_EVENT(block_rq, block_rq_issue, | 153 | DEFINE_EVENT(block_rq, block_rq_issue, |
106 | 154 | ||
107 | TP_PROTO(struct request_queue *q, struct request *rq), | 155 | TP_PROTO(struct request_queue *q, struct request *rq), |
@@ -109,6 +157,17 @@ DEFINE_EVENT(block_rq, block_rq_issue, | |||
109 | TP_ARGS(q, rq) | 157 | TP_ARGS(q, rq) |
110 | ); | 158 | ); |
111 | 159 | ||
160 | /** | ||
161 | * block_bio_bounce - used bounce buffer when processing block operation | ||
162 | * @q: queue holding the block operation | ||
163 | * @bio: block operation | ||
164 | * | ||
165 | * A bounce buffer was used to handle the block operation @bio in @q. | ||
166 | * This occurs when hardware limitations prevent a direct transfer of | ||
167 | * data between the @bio data memory area and the IO device. Use of a | ||
168 | * bounce buffer requires extra copying of data and decreases | ||
169 | * performance. | ||
170 | */ | ||
112 | TRACE_EVENT(block_bio_bounce, | 171 | TRACE_EVENT(block_bio_bounce, |
113 | 172 | ||
114 | TP_PROTO(struct request_queue *q, struct bio *bio), | 173 | TP_PROTO(struct request_queue *q, struct bio *bio), |
@@ -138,6 +197,14 @@ TRACE_EVENT(block_bio_bounce, | |||
138 | __entry->nr_sector, __entry->comm) | 197 | __entry->nr_sector, __entry->comm) |
139 | ); | 198 | ); |
140 | 199 | ||
200 | /** | ||
201 | * block_bio_complete - completed all work on the block operation | ||
202 | * @q: queue holding the block operation | ||
203 | * @bio: block operation completed | ||
204 | * | ||
205 | * This tracepoint indicates there is no further work to do on this | ||
206 | * block IO operation @bio. | ||
207 | */ | ||
141 | TRACE_EVENT(block_bio_complete, | 208 | TRACE_EVENT(block_bio_complete, |
142 | 209 | ||
143 | TP_PROTO(struct request_queue *q, struct bio *bio), | 210 | TP_PROTO(struct request_queue *q, struct bio *bio), |
@@ -193,6 +260,14 @@ DECLARE_EVENT_CLASS(block_bio, | |||
193 | __entry->nr_sector, __entry->comm) | 260 | __entry->nr_sector, __entry->comm) |
194 | ); | 261 | ); |
195 | 262 | ||
263 | /** | ||
264 | * block_bio_backmerge - merging block operation to the end of an existing operation | ||
265 | * @q: queue holding operation | ||
266 | * @bio: new block operation to merge | ||
267 | * | ||
268 | * Merging block request @bio to the end of an existing block request | ||
269 | * in queue @q. | ||
270 | */ | ||
196 | DEFINE_EVENT(block_bio, block_bio_backmerge, | 271 | DEFINE_EVENT(block_bio, block_bio_backmerge, |
197 | 272 | ||
198 | TP_PROTO(struct request_queue *q, struct bio *bio), | 273 | TP_PROTO(struct request_queue *q, struct bio *bio), |
@@ -200,6 +275,14 @@ DEFINE_EVENT(block_bio, block_bio_backmerge, | |||
200 | TP_ARGS(q, bio) | 275 | TP_ARGS(q, bio) |
201 | ); | 276 | ); |
202 | 277 | ||
278 | /** | ||
279 | * block_bio_frontmerge - merging block operation to the beginning of an existing operation | ||
280 | * @q: queue holding operation | ||
281 | * @bio: new block operation to merge | ||
282 | * | ||
283 | * Merging block IO operation @bio to the beginning of an existing block | ||
284 | * operation in queue @q. | ||
285 | */ | ||
203 | DEFINE_EVENT(block_bio, block_bio_frontmerge, | 286 | DEFINE_EVENT(block_bio, block_bio_frontmerge, |
204 | 287 | ||
205 | TP_PROTO(struct request_queue *q, struct bio *bio), | 288 | TP_PROTO(struct request_queue *q, struct bio *bio), |
@@ -207,6 +290,13 @@ DEFINE_EVENT(block_bio, block_bio_frontmerge, | |||
207 | TP_ARGS(q, bio) | 290 | TP_ARGS(q, bio) |
208 | ); | 291 | ); |
209 | 292 | ||
293 | /** | ||
294 | * block_bio_queue - putting new block IO operation in queue | ||
295 | * @q: queue holding operation | ||
296 | * @bio: new block operation | ||
297 | * | ||
298 | * About to place the block IO operation @bio into queue @q. | ||
299 | */ | ||
210 | DEFINE_EVENT(block_bio, block_bio_queue, | 300 | DEFINE_EVENT(block_bio, block_bio_queue, |
211 | 301 | ||
212 | TP_PROTO(struct request_queue *q, struct bio *bio), | 302 | TP_PROTO(struct request_queue *q, struct bio *bio), |
@@ -243,6 +333,15 @@ DECLARE_EVENT_CLASS(block_get_rq, | |||
243 | __entry->nr_sector, __entry->comm) | 333 | __entry->nr_sector, __entry->comm) |
244 | ); | 334 | ); |
245 | 335 | ||
336 | /** | ||
337 | * block_getrq - get a free request entry in queue for block IO operations | ||
338 | * @q: queue for operations | ||
339 | * @bio: pending block IO operation | ||
340 | * @rw: low bit indicates a read (%0) or a write (%1) | ||
341 | * | ||
342 | * A request struct for queue @q has been allocated to handle the | ||
343 | * block IO operation @bio. | ||
344 | */ | ||
246 | DEFINE_EVENT(block_get_rq, block_getrq, | 345 | DEFINE_EVENT(block_get_rq, block_getrq, |
247 | 346 | ||
248 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), | 347 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), |
@@ -250,6 +349,17 @@ DEFINE_EVENT(block_get_rq, block_getrq, | |||
250 | TP_ARGS(q, bio, rw) | 349 | TP_ARGS(q, bio, rw) |
251 | ); | 350 | ); |
252 | 351 | ||
352 | /** | ||
353 | * block_sleeprq - waiting to get a free request entry in queue for block IO operation | ||
354 | * @q: queue for operation | ||
355 | * @bio: pending block IO operation | ||
356 | * @rw: low bit indicates a read (%0) or a write (%1) | ||
357 | * | ||
358 | * In the case where a request struct cannot be provided for queue @q | ||
359 | * the process needs to wait for an request struct to become | ||
360 | * available. This tracepoint event is generated each time the | ||
361 | * process goes to sleep waiting for request struct become available. | ||
362 | */ | ||
253 | DEFINE_EVENT(block_get_rq, block_sleeprq, | 363 | DEFINE_EVENT(block_get_rq, block_sleeprq, |
254 | 364 | ||
255 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), | 365 | TP_PROTO(struct request_queue *q, struct bio *bio, int rw), |
@@ -257,6 +367,14 @@ DEFINE_EVENT(block_get_rq, block_sleeprq, | |||
257 | TP_ARGS(q, bio, rw) | 367 | TP_ARGS(q, bio, rw) |
258 | ); | 368 | ); |
259 | 369 | ||
370 | /** | ||
371 | * block_plug - keep operations requests in request queue | ||
372 | * @q: request queue to plug | ||
373 | * | ||
374 | * Plug the request queue @q. Do not allow block operation requests | ||
375 | * to be sent to the device driver. Instead, accumulate requests in | ||
376 | * the queue to improve throughput performance of the block device. | ||
377 | */ | ||
260 | TRACE_EVENT(block_plug, | 378 | TRACE_EVENT(block_plug, |
261 | 379 | ||
262 | TP_PROTO(struct request_queue *q), | 380 | TP_PROTO(struct request_queue *q), |
@@ -293,6 +411,13 @@ DECLARE_EVENT_CLASS(block_unplug, | |||
293 | TP_printk("[%s] %d", __entry->comm, __entry->nr_rq) | 411 | TP_printk("[%s] %d", __entry->comm, __entry->nr_rq) |
294 | ); | 412 | ); |
295 | 413 | ||
414 | /** | ||
415 | * block_unplug_timer - timed release of operations requests in queue to device driver | ||
416 | * @q: request queue to unplug | ||
417 | * | ||
418 | * Unplug the request queue @q because a timer expired and allow block | ||
419 | * operation requests to be sent to the device driver. | ||
420 | */ | ||
296 | DEFINE_EVENT(block_unplug, block_unplug_timer, | 421 | DEFINE_EVENT(block_unplug, block_unplug_timer, |
297 | 422 | ||
298 | TP_PROTO(struct request_queue *q), | 423 | TP_PROTO(struct request_queue *q), |
@@ -300,6 +425,13 @@ DEFINE_EVENT(block_unplug, block_unplug_timer, | |||
300 | TP_ARGS(q) | 425 | TP_ARGS(q) |
301 | ); | 426 | ); |
302 | 427 | ||
428 | /** | ||
429 | * block_unplug_io - release of operations requests in request queue | ||
430 | * @q: request queue to unplug | ||
431 | * | ||
432 | * Unplug request queue @q because device driver is scheduled to work | ||
433 | * on elements in the request queue. | ||
434 | */ | ||
303 | DEFINE_EVENT(block_unplug, block_unplug_io, | 435 | DEFINE_EVENT(block_unplug, block_unplug_io, |
304 | 436 | ||
305 | TP_PROTO(struct request_queue *q), | 437 | TP_PROTO(struct request_queue *q), |
@@ -307,6 +439,17 @@ DEFINE_EVENT(block_unplug, block_unplug_io, | |||
307 | TP_ARGS(q) | 439 | TP_ARGS(q) |
308 | ); | 440 | ); |
309 | 441 | ||
442 | /** | ||
443 | * block_split - split a single bio struct into two bio structs | ||
444 | * @q: queue containing the bio | ||
445 | * @bio: block operation being split | ||
446 | * @new_sector: The starting sector for the new bio | ||
447 | * | ||
448 | * The bio request @bio in request queue @q needs to be split into two | ||
449 | * bio requests. The newly created @bio request starts at | ||
450 | * @new_sector. This split may be required due to hardware limitation | ||
451 | * such as operation crossing device boundaries in a RAID system. | ||
452 | */ | ||
310 | TRACE_EVENT(block_split, | 453 | TRACE_EVENT(block_split, |
311 | 454 | ||
312 | TP_PROTO(struct request_queue *q, struct bio *bio, | 455 | TP_PROTO(struct request_queue *q, struct bio *bio, |
@@ -337,6 +480,16 @@ TRACE_EVENT(block_split, | |||
337 | __entry->comm) | 480 | __entry->comm) |
338 | ); | 481 | ); |
339 | 482 | ||
483 | /** | ||
484 | * block_remap - map request for a partition to the raw device | ||
485 | * @q: queue holding the operation | ||
486 | * @bio: revised operation | ||
487 | * @dev: device for the operation | ||
488 | * @from: original sector for the operation | ||
489 | * | ||
490 | * An operation for a partition on a block device has been mapped to the | ||
491 | * raw block device. | ||
492 | */ | ||
340 | TRACE_EVENT(block_remap, | 493 | TRACE_EVENT(block_remap, |
341 | 494 | ||
342 | TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, | 495 | TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, |
@@ -370,6 +523,17 @@ TRACE_EVENT(block_remap, | |||
370 | (unsigned long long)__entry->old_sector) | 523 | (unsigned long long)__entry->old_sector) |
371 | ); | 524 | ); |
372 | 525 | ||
526 | /** | ||
527 | * block_rq_remap - map request for a block operation request | ||
528 | * @q: queue holding the operation | ||
529 | * @rq: block IO operation request | ||
530 | * @dev: device for the operation | ||
531 | * @from: original sector for the operation | ||
532 | * | ||
533 | * The block operation request @rq in @q has been remapped. The block | ||
534 | * operation request @rq holds the current information and @from hold | ||
535 | * the original sector. | ||
536 | */ | ||
373 | TRACE_EVENT(block_rq_remap, | 537 | TRACE_EVENT(block_rq_remap, |
374 | 538 | ||
375 | TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, | 539 | TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, |
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index b17d49dfc3ef..6dd3a51ab1cb 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | #undef TRACE_SYSTEM | 6 | #undef TRACE_SYSTEM |
7 | #define TRACE_SYSTEM kvm | 7 | #define TRACE_SYSTEM kvm |
8 | #define TRACE_INCLUDE_FILE kvm | ||
9 | 8 | ||
10 | #if defined(__KVM_HAVE_IOAPIC) | 9 | #if defined(__KVM_HAVE_IOAPIC) |
11 | TRACE_EVENT(kvm_set_irq, | 10 | TRACE_EVENT(kvm_set_irq, |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 4d2289626a84..a8c96212bc1b 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
420 | * User space encodes device types as two-byte values, | 420 | * User space encodes device types as two-byte values, |
421 | * so we need to recode them | 421 | * so we need to recode them |
422 | */ | 422 | */ |
423 | swdev = old_decode_dev(swap_area.dev); | 423 | swdev = new_decode_dev(swap_area.dev); |
424 | if (swdev) { | 424 | if (swdev) { |
425 | offset = swap_area.offset; | 425 | offset = swap_area.offset; |
426 | data->swap = swap_type_of(swdev, offset, NULL); | 426 | data->swap = swap_type_of(swdev, offset, NULL); |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 63fe25433980..03a7ea1579f6 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -69,6 +69,13 @@ EXPORT_SYMBOL_GPL(rcu_scheduler_active); | |||
69 | 69 | ||
70 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 70 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
71 | 71 | ||
72 | int debug_lockdep_rcu_enabled(void) | ||
73 | { | ||
74 | return rcu_scheduler_active && debug_locks && | ||
75 | current->lockdep_recursion == 0; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); | ||
78 | |||
72 | /** | 79 | /** |
73 | * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? | 80 | * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? |
74 | * | 81 | * |
diff --git a/kernel/sched.c b/kernel/sched.c index 8cafe3ff558f..b0bbadc24955 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4860,7 +4860,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, | |||
4860 | int ret; | 4860 | int ret; |
4861 | cpumask_var_t mask; | 4861 | cpumask_var_t mask; |
4862 | 4862 | ||
4863 | if (len < nr_cpu_ids) | 4863 | if ((len * BITS_PER_BYTE) < nr_cpu_ids) |
4864 | return -EINVAL; | 4864 | return -EINVAL; |
4865 | if (len & (sizeof(unsigned long)-1)) | 4865 | if (len & (sizeof(unsigned long)-1)) |
4866 | return -EINVAL; | 4866 | return -EINVAL; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ff017108700d..935248bdbc47 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -356,7 +356,7 @@ config SLUB_STATS | |||
356 | config DEBUG_KMEMLEAK | 356 | config DEBUG_KMEMLEAK |
357 | bool "Kernel memory leak detector" | 357 | bool "Kernel memory leak detector" |
358 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ | 358 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ |
359 | (X86 || ARM || PPC || S390 || SUPERH || MICROBLAZE) | 359 | (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE) |
360 | 360 | ||
361 | select DEBUG_FS if SYSFS | 361 | select DEBUG_FS if SYSFS |
362 | select STACKTRACE if STACKTRACE_SUPPORT | 362 | select STACKTRACE if STACKTRACE_SUPPORT |
diff --git a/lib/Makefile b/lib/Makefile index 2e152aed7198..0d4015205c64 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o | |||
21 | 21 | ||
22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
24 | string_helpers.o gcd.o list_sort.o | 24 | string_helpers.o gcd.o lcm.o list_sort.o |
25 | 25 | ||
26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) | 26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) |
27 | CFLAGS_kobject.o += -DDEBUG | 27 | CFLAGS_kobject.o += -DDEBUG |
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index ba8b67039d13..01e64270e246 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf, | |||
570 | * Now parse out the first token and use it as the name for the | 570 | * Now parse out the first token and use it as the name for the |
571 | * driver to filter for. | 571 | * driver to filter for. |
572 | */ | 572 | */ |
573 | for (i = 0; i < NAME_MAX_LEN; ++i) { | 573 | for (i = 0; i < NAME_MAX_LEN - 1; ++i) { |
574 | current_driver_name[i] = buf[i]; | 574 | current_driver_name[i] = buf[i]; |
575 | if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0) | 575 | if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0) |
576 | break; | 576 | break; |
diff --git a/lib/lcm.c b/lib/lcm.c new file mode 100644 index 000000000000..157cd88a6ffc --- /dev/null +++ b/lib/lcm.c | |||
@@ -0,0 +1,15 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/gcd.h> | ||
3 | #include <linux/module.h> | ||
4 | |||
5 | /* Lowest common multiple */ | ||
6 | unsigned long lcm(unsigned long a, unsigned long b) | ||
7 | { | ||
8 | if (a && b) | ||
9 | return (a * b) / gcd(a, b); | ||
10 | else if (b) | ||
11 | return b; | ||
12 | |||
13 | return a; | ||
14 | } | ||
15 | EXPORT_SYMBOL_GPL(lcm); | ||
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 0871582aa29d..2a087e0f9863 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -555,6 +555,10 @@ EXPORT_SYMBOL(radix_tree_tag_clear); | |||
555 | * | 555 | * |
556 | * 0: tag not present or not set | 556 | * 0: tag not present or not set |
557 | * 1: tag set | 557 | * 1: tag set |
558 | * | ||
559 | * Note that the return value of this function may not be relied on, even if | ||
560 | * the RCU lock is held, unless tag modification and node deletion are excluded | ||
561 | * from concurrency. | ||
558 | */ | 562 | */ |
559 | int radix_tree_tag_get(struct radix_tree_root *root, | 563 | int radix_tree_tag_get(struct radix_tree_root *root, |
560 | unsigned long index, unsigned int tag) | 564 | unsigned long index, unsigned int tag) |
@@ -595,12 +599,8 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
595 | */ | 599 | */ |
596 | if (!tag_get(node, tag, offset)) | 600 | if (!tag_get(node, tag, offset)) |
597 | saw_unset_tag = 1; | 601 | saw_unset_tag = 1; |
598 | if (height == 1) { | 602 | if (height == 1) |
599 | int ret = tag_get(node, tag, offset); | 603 | return !!tag_get(node, tag, offset); |
600 | |||
601 | BUG_ON(ret && saw_unset_tag); | ||
602 | return !!ret; | ||
603 | } | ||
604 | node = rcu_dereference_raw(node->slots[offset]); | 604 | node = rcu_dereference_raw(node->slots[offset]); |
605 | shift -= RADIX_TREE_MAP_SHIFT; | 605 | shift -= RADIX_TREE_MAP_SHIFT; |
606 | height--; | 606 | height--; |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 24112e5a5780..7376b7c55ffe 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -408,12 +408,12 @@ enum format_type { | |||
408 | }; | 408 | }; |
409 | 409 | ||
410 | struct printf_spec { | 410 | struct printf_spec { |
411 | u16 type; | 411 | u8 type; /* format_type enum */ |
412 | s16 field_width; /* width of output field */ | ||
413 | u8 flags; /* flags to number() */ | 412 | u8 flags; /* flags to number() */ |
414 | u8 base; | 413 | u8 base; /* number base, 8, 10 or 16 only */ |
415 | s8 precision; /* # of digits/chars */ | 414 | u8 qualifier; /* number qualifier, one of 'hHlLtzZ' */ |
416 | u8 qualifier; | 415 | s16 field_width; /* width of output field */ |
416 | s16 precision; /* # of digits/chars */ | ||
417 | }; | 417 | }; |
418 | 418 | ||
419 | static char *number(char *buf, char *end, unsigned long long num, | 419 | static char *number(char *buf, char *end, unsigned long long num, |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 0e8ca0347707..f13e067e1467 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -227,6 +227,9 @@ static struct device_attribute bdi_dev_attrs[] = { | |||
227 | static __init int bdi_class_init(void) | 227 | static __init int bdi_class_init(void) |
228 | { | 228 | { |
229 | bdi_class = class_create(THIS_MODULE, "bdi"); | 229 | bdi_class = class_create(THIS_MODULE, "bdi"); |
230 | if (IS_ERR(bdi_class)) | ||
231 | return PTR_ERR(bdi_class); | ||
232 | |||
230 | bdi_class->dev_attrs = bdi_dev_attrs; | 233 | bdi_class->dev_attrs = bdi_dev_attrs; |
231 | bdi_debug_init(); | 234 | bdi_debug_init(); |
232 | return 0; | 235 | return 0; |
@@ -507,11 +507,12 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start, | |||
507 | struct address_space *mapping = NULL; | 507 | struct address_space *mapping = NULL; |
508 | struct prio_tree_root *root = NULL; | 508 | struct prio_tree_root *root = NULL; |
509 | struct file *file = vma->vm_file; | 509 | struct file *file = vma->vm_file; |
510 | struct anon_vma *anon_vma = NULL; | ||
511 | long adjust_next = 0; | 510 | long adjust_next = 0; |
512 | int remove_next = 0; | 511 | int remove_next = 0; |
513 | 512 | ||
514 | if (next && !insert) { | 513 | if (next && !insert) { |
514 | struct vm_area_struct *exporter = NULL; | ||
515 | |||
515 | if (end >= next->vm_end) { | 516 | if (end >= next->vm_end) { |
516 | /* | 517 | /* |
517 | * vma expands, overlapping all the next, and | 518 | * vma expands, overlapping all the next, and |
@@ -519,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start, | |||
519 | */ | 520 | */ |
520 | again: remove_next = 1 + (end > next->vm_end); | 521 | again: remove_next = 1 + (end > next->vm_end); |
521 | end = next->vm_end; | 522 | end = next->vm_end; |
522 | anon_vma = next->anon_vma; | 523 | exporter = next; |
523 | importer = vma; | 524 | importer = vma; |
524 | } else if (end > next->vm_start) { | 525 | } else if (end > next->vm_start) { |
525 | /* | 526 | /* |
@@ -527,7 +528,7 @@ again: remove_next = 1 + (end > next->vm_end); | |||
527 | * mprotect case 5 shifting the boundary up. | 528 | * mprotect case 5 shifting the boundary up. |
528 | */ | 529 | */ |
529 | adjust_next = (end - next->vm_start) >> PAGE_SHIFT; | 530 | adjust_next = (end - next->vm_start) >> PAGE_SHIFT; |
530 | anon_vma = next->anon_vma; | 531 | exporter = next; |
531 | importer = vma; | 532 | importer = vma; |
532 | } else if (end < vma->vm_end) { | 533 | } else if (end < vma->vm_end) { |
533 | /* | 534 | /* |
@@ -536,28 +537,19 @@ again: remove_next = 1 + (end > next->vm_end); | |||
536 | * mprotect case 4 shifting the boundary down. | 537 | * mprotect case 4 shifting the boundary down. |
537 | */ | 538 | */ |
538 | adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT); | 539 | adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT); |
539 | anon_vma = next->anon_vma; | 540 | exporter = vma; |
540 | importer = next; | 541 | importer = next; |
541 | } | 542 | } |
542 | } | ||
543 | 543 | ||
544 | /* | ||
545 | * When changing only vma->vm_end, we don't really need anon_vma lock. | ||
546 | */ | ||
547 | if (vma->anon_vma && (insert || importer || start != vma->vm_start)) | ||
548 | anon_vma = vma->anon_vma; | ||
549 | if (anon_vma) { | ||
550 | /* | 544 | /* |
551 | * Easily overlooked: when mprotect shifts the boundary, | 545 | * Easily overlooked: when mprotect shifts the boundary, |
552 | * make sure the expanding vma has anon_vma set if the | 546 | * make sure the expanding vma has anon_vma set if the |
553 | * shrinking vma had, to cover any anon pages imported. | 547 | * shrinking vma had, to cover any anon pages imported. |
554 | */ | 548 | */ |
555 | if (importer && !importer->anon_vma) { | 549 | if (exporter && exporter->anon_vma && !importer->anon_vma) { |
556 | /* Block reverse map lookups until things are set up. */ | 550 | if (anon_vma_clone(importer, exporter)) |
557 | if (anon_vma_clone(importer, vma)) { | ||
558 | return -ENOMEM; | 551 | return -ENOMEM; |
559 | } | 552 | importer->anon_vma = exporter->anon_vma; |
560 | importer->anon_vma = anon_vma; | ||
561 | } | 553 | } |
562 | } | 554 | } |
563 | 555 | ||
@@ -825,6 +817,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, | |||
825 | } | 817 | } |
826 | 818 | ||
827 | /* | 819 | /* |
820 | * Rough compatbility check to quickly see if it's even worth looking | ||
821 | * at sharing an anon_vma. | ||
822 | * | ||
823 | * They need to have the same vm_file, and the flags can only differ | ||
824 | * in things that mprotect may change. | ||
825 | * | ||
826 | * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that | ||
827 | * we can merge the two vma's. For example, we refuse to merge a vma if | ||
828 | * there is a vm_ops->close() function, because that indicates that the | ||
829 | * driver is doing some kind of reference counting. But that doesn't | ||
830 | * really matter for the anon_vma sharing case. | ||
831 | */ | ||
832 | static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b) | ||
833 | { | ||
834 | return a->vm_end == b->vm_start && | ||
835 | mpol_equal(vma_policy(a), vma_policy(b)) && | ||
836 | a->vm_file == b->vm_file && | ||
837 | !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) && | ||
838 | b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT); | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * Do some basic sanity checking to see if we can re-use the anon_vma | ||
843 | * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be | ||
844 | * the same as 'old', the other will be the new one that is trying | ||
845 | * to share the anon_vma. | ||
846 | * | ||
847 | * NOTE! This runs with mm_sem held for reading, so it is possible that | ||
848 | * the anon_vma of 'old' is concurrently in the process of being set up | ||
849 | * by another page fault trying to merge _that_. But that's ok: if it | ||
850 | * is being set up, that automatically means that it will be a singleton | ||
851 | * acceptable for merging, so we can do all of this optimistically. But | ||
852 | * we do that ACCESS_ONCE() to make sure that we never re-load the pointer. | ||
853 | * | ||
854 | * IOW: that the "list_is_singular()" test on the anon_vma_chain only | ||
855 | * matters for the 'stable anon_vma' case (ie the thing we want to avoid | ||
856 | * is to return an anon_vma that is "complex" due to having gone through | ||
857 | * a fork). | ||
858 | * | ||
859 | * We also make sure that the two vma's are compatible (adjacent, | ||
860 | * and with the same memory policies). That's all stable, even with just | ||
861 | * a read lock on the mm_sem. | ||
862 | */ | ||
863 | static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b) | ||
864 | { | ||
865 | if (anon_vma_compatible(a, b)) { | ||
866 | struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma); | ||
867 | |||
868 | if (anon_vma && list_is_singular(&old->anon_vma_chain)) | ||
869 | return anon_vma; | ||
870 | } | ||
871 | return NULL; | ||
872 | } | ||
873 | |||
874 | /* | ||
828 | * find_mergeable_anon_vma is used by anon_vma_prepare, to check | 875 | * find_mergeable_anon_vma is used by anon_vma_prepare, to check |
829 | * neighbouring vmas for a suitable anon_vma, before it goes off | 876 | * neighbouring vmas for a suitable anon_vma, before it goes off |
830 | * to allocate a new anon_vma. It checks because a repetitive | 877 | * to allocate a new anon_vma. It checks because a repetitive |
@@ -834,28 +881,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, | |||
834 | */ | 881 | */ |
835 | struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) | 882 | struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma) |
836 | { | 883 | { |
884 | struct anon_vma *anon_vma; | ||
837 | struct vm_area_struct *near; | 885 | struct vm_area_struct *near; |
838 | unsigned long vm_flags; | ||
839 | 886 | ||
840 | near = vma->vm_next; | 887 | near = vma->vm_next; |
841 | if (!near) | 888 | if (!near) |
842 | goto try_prev; | 889 | goto try_prev; |
843 | 890 | ||
844 | /* | 891 | anon_vma = reusable_anon_vma(near, vma, near); |
845 | * Since only mprotect tries to remerge vmas, match flags | 892 | if (anon_vma) |
846 | * which might be mprotected into each other later on. | 893 | return anon_vma; |
847 | * Neither mlock nor madvise tries to remerge at present, | ||
848 | * so leave their flags as obstructing a merge. | ||
849 | */ | ||
850 | vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC); | ||
851 | vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC); | ||
852 | |||
853 | if (near->anon_vma && vma->vm_end == near->vm_start && | ||
854 | mpol_equal(vma_policy(vma), vma_policy(near)) && | ||
855 | can_vma_merge_before(near, vm_flags, | ||
856 | NULL, vma->vm_file, vma->vm_pgoff + | ||
857 | ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT))) | ||
858 | return near->anon_vma; | ||
859 | try_prev: | 894 | try_prev: |
860 | /* | 895 | /* |
861 | * It is potentially slow to have to call find_vma_prev here. | 896 | * It is potentially slow to have to call find_vma_prev here. |
@@ -868,14 +903,9 @@ try_prev: | |||
868 | if (!near) | 903 | if (!near) |
869 | goto none; | 904 | goto none; |
870 | 905 | ||
871 | vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC); | 906 | anon_vma = reusable_anon_vma(near, near, vma); |
872 | vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC); | 907 | if (anon_vma) |
873 | 908 | return anon_vma; | |
874 | if (near->anon_vma && near->vm_end == vma->vm_start && | ||
875 | mpol_equal(vma_policy(near), vma_policy(vma)) && | ||
876 | can_vma_merge_after(near, vm_flags, | ||
877 | NULL, vma->vm_file, vma->vm_pgoff)) | ||
878 | return near->anon_vma; | ||
879 | none: | 909 | none: |
880 | /* | 910 | /* |
881 | * There's no absolute need to look only at touching neighbours: | 911 | * There's no absolute need to look only at touching neighbours: |
@@ -182,7 +182,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) | |||
182 | { | 182 | { |
183 | struct anon_vma_chain *avc, *pavc; | 183 | struct anon_vma_chain *avc, *pavc; |
184 | 184 | ||
185 | list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) { | 185 | list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) { |
186 | avc = anon_vma_chain_alloc(); | 186 | avc = anon_vma_chain_alloc(); |
187 | if (!avc) | 187 | if (!avc) |
188 | goto enomem_failure; | 188 | goto enomem_failure; |
@@ -730,13 +730,29 @@ void page_move_anon_rmap(struct page *page, | |||
730 | * @page: the page to add the mapping to | 730 | * @page: the page to add the mapping to |
731 | * @vma: the vm area in which the mapping is added | 731 | * @vma: the vm area in which the mapping is added |
732 | * @address: the user virtual address mapped | 732 | * @address: the user virtual address mapped |
733 | * @exclusive: the page is exclusively owned by the current process | ||
733 | */ | 734 | */ |
734 | static void __page_set_anon_rmap(struct page *page, | 735 | static void __page_set_anon_rmap(struct page *page, |
735 | struct vm_area_struct *vma, unsigned long address) | 736 | struct vm_area_struct *vma, unsigned long address, int exclusive) |
736 | { | 737 | { |
737 | struct anon_vma *anon_vma = vma->anon_vma; | 738 | struct anon_vma *anon_vma = vma->anon_vma; |
738 | 739 | ||
739 | BUG_ON(!anon_vma); | 740 | BUG_ON(!anon_vma); |
741 | |||
742 | /* | ||
743 | * If the page isn't exclusively mapped into this vma, | ||
744 | * we must use the _oldest_ possible anon_vma for the | ||
745 | * page mapping! | ||
746 | * | ||
747 | * So take the last AVC chain entry in the vma, which is | ||
748 | * the deepest ancestor, and use the anon_vma from that. | ||
749 | */ | ||
750 | if (!exclusive) { | ||
751 | struct anon_vma_chain *avc; | ||
752 | avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma); | ||
753 | anon_vma = avc->anon_vma; | ||
754 | } | ||
755 | |||
740 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; | 756 | anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON; |
741 | page->mapping = (struct address_space *) anon_vma; | 757 | page->mapping = (struct address_space *) anon_vma; |
742 | page->index = linear_page_index(vma, address); | 758 | page->index = linear_page_index(vma, address); |
@@ -791,7 +807,7 @@ void page_add_anon_rmap(struct page *page, | |||
791 | VM_BUG_ON(!PageLocked(page)); | 807 | VM_BUG_ON(!PageLocked(page)); |
792 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); | 808 | VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
793 | if (first) | 809 | if (first) |
794 | __page_set_anon_rmap(page, vma, address); | 810 | __page_set_anon_rmap(page, vma, address, 0); |
795 | else | 811 | else |
796 | __page_check_anon_rmap(page, vma, address); | 812 | __page_check_anon_rmap(page, vma, address); |
797 | } | 813 | } |
@@ -813,7 +829,7 @@ void page_add_new_anon_rmap(struct page *page, | |||
813 | SetPageSwapBacked(page); | 829 | SetPageSwapBacked(page); |
814 | atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */ | 830 | atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */ |
815 | __inc_zone_page_state(page, NR_ANON_PAGES); | 831 | __inc_zone_page_state(page, NR_ANON_PAGES); |
816 | __page_set_anon_rmap(page, vma, address); | 832 | __page_set_anon_rmap(page, vma, address, 1); |
817 | if (page_evictable(page, vma)) | 833 | if (page_evictable(page, vma)) |
818 | lru_cache_add_lru(page, LRU_ACTIVE_ANON); | 834 | lru_cache_add_lru(page, LRU_ACTIVE_ANON); |
819 | else | 835 | else |
@@ -3602,21 +3602,10 @@ EXPORT_SYMBOL(kmem_cache_alloc_notrace); | |||
3602 | */ | 3602 | */ |
3603 | int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr) | 3603 | int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr) |
3604 | { | 3604 | { |
3605 | unsigned long addr = (unsigned long)ptr; | ||
3606 | unsigned long min_addr = PAGE_OFFSET; | ||
3607 | unsigned long align_mask = BYTES_PER_WORD - 1; | ||
3608 | unsigned long size = cachep->buffer_size; | 3605 | unsigned long size = cachep->buffer_size; |
3609 | struct page *page; | 3606 | struct page *page; |
3610 | 3607 | ||
3611 | if (unlikely(addr < min_addr)) | 3608 | if (unlikely(!kern_ptr_validate(ptr, size))) |
3612 | goto out; | ||
3613 | if (unlikely(addr > (unsigned long)high_memory - size)) | ||
3614 | goto out; | ||
3615 | if (unlikely(addr & align_mask)) | ||
3616 | goto out; | ||
3617 | if (unlikely(!kern_addr_valid(addr))) | ||
3618 | goto out; | ||
3619 | if (unlikely(!kern_addr_valid(addr + size - 1))) | ||
3620 | goto out; | 3609 | goto out; |
3621 | page = virt_to_page(ptr); | 3610 | page = virt_to_page(ptr); |
3622 | if (unlikely(!PageSlab(page))) | 3611 | if (unlikely(!PageSlab(page))) |
@@ -2386,6 +2386,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object) | |||
2386 | { | 2386 | { |
2387 | struct page *page; | 2387 | struct page *page; |
2388 | 2388 | ||
2389 | if (!kern_ptr_validate(object, s->size)) | ||
2390 | return 0; | ||
2391 | |||
2389 | page = get_object_page(object); | 2392 | page = get_object_page(object); |
2390 | 2393 | ||
2391 | if (!page || s != page->slab) | 2394 | if (!page || s != page->slab) |
@@ -186,6 +186,27 @@ void kzfree(const void *p) | |||
186 | } | 186 | } |
187 | EXPORT_SYMBOL(kzfree); | 187 | EXPORT_SYMBOL(kzfree); |
188 | 188 | ||
189 | int kern_ptr_validate(const void *ptr, unsigned long size) | ||
190 | { | ||
191 | unsigned long addr = (unsigned long)ptr; | ||
192 | unsigned long min_addr = PAGE_OFFSET; | ||
193 | unsigned long align_mask = sizeof(void *) - 1; | ||
194 | |||
195 | if (unlikely(addr < min_addr)) | ||
196 | goto out; | ||
197 | if (unlikely(addr > (unsigned long)high_memory - size)) | ||
198 | goto out; | ||
199 | if (unlikely(addr & align_mask)) | ||
200 | goto out; | ||
201 | if (unlikely(!kern_addr_valid(addr))) | ||
202 | goto out; | ||
203 | if (unlikely(!kern_addr_valid(addr + size - 1))) | ||
204 | goto out; | ||
205 | return 1; | ||
206 | out: | ||
207 | return 0; | ||
208 | } | ||
209 | |||
189 | /* | 210 | /* |
190 | * strndup_user - duplicate an existing string from user space | 211 | * strndup_user - duplicate an existing string from user space |
191 | * @s: The string to duplicate | 212 | * @s: The string to duplicate |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 6980625537ca..f29ada827a6a 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -723,7 +723,7 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
723 | if (!pskb_may_pull(skb, len)) | 723 | if (!pskb_may_pull(skb, len)) |
724 | return -EINVAL; | 724 | return -EINVAL; |
725 | 725 | ||
726 | grec = (void *)(skb->data + len); | 726 | grec = (void *)(skb->data + len - sizeof(*grec)); |
727 | group = grec->grec_mca; | 727 | group = grec->grec_mca; |
728 | type = grec->grec_type; | 728 | type = grec->grec_type; |
729 | 729 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index 3a7dffb6519c..da99cf153b33 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -445,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, | |||
445 | return -EFAULT; | 445 | return -EFAULT; |
446 | } | 446 | } |
447 | } else if (count == 1) { | 447 | } else if (count == 1) { |
448 | if (copy_from_user(&sfilter, optval, optlen)) | 448 | if (copy_from_user(&sfilter, optval, sizeof(sfilter))) |
449 | return -EFAULT; | 449 | return -EFAULT; |
450 | } | 450 | } |
451 | 451 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 1c8a0ce473a8..92584bfef09b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1989,8 +1989,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
1989 | if (dev->real_num_tx_queues > 1) | 1989 | if (dev->real_num_tx_queues > 1) |
1990 | queue_index = skb_tx_hash(dev, skb); | 1990 | queue_index = skb_tx_hash(dev, skb); |
1991 | 1991 | ||
1992 | if (sk && sk->sk_dst_cache) | 1992 | if (sk) { |
1993 | sk_tx_queue_set(sk, queue_index); | 1993 | struct dst_entry *dst = rcu_dereference(sk->sk_dst_cache); |
1994 | |||
1995 | if (dst && skb_dst(skb) == dst) | ||
1996 | sk_tx_queue_set(sk, queue_index); | ||
1997 | } | ||
1994 | } | 1998 | } |
1995 | } | 1999 | } |
1996 | 2000 | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 59a838795e3e..c98f115fb0fd 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -209,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) | |||
209 | { | 209 | { |
210 | struct node *ret = tnode_get_child(tn, i); | 210 | struct node *ret = tnode_get_child(tn, i); |
211 | 211 | ||
212 | return rcu_dereference(ret); | 212 | return rcu_dereference_check(ret, |
213 | rcu_read_lock_held() || | ||
214 | lockdep_rtnl_is_held()); | ||
213 | } | 215 | } |
214 | 216 | ||
215 | static inline int tnode_child_length(const struct tnode *tn) | 217 | static inline int tnode_child_length(const struct tnode *tn) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index c65f18e0936e..d1bcc9f21d4f 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -120,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
120 | newskb->pkt_type = PACKET_LOOPBACK; | 120 | newskb->pkt_type = PACKET_LOOPBACK; |
121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 121 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
122 | WARN_ON(!skb_dst(newskb)); | 122 | WARN_ON(!skb_dst(newskb)); |
123 | netif_rx(newskb); | 123 | netif_rx_ni(newskb); |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 954bbfb39dff..8fef859db35d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -472,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
472 | if (hslot->count < hslot2->count) | 472 | if (hslot->count < hslot2->count) |
473 | goto begin; | 473 | goto begin; |
474 | 474 | ||
475 | result = udp4_lib_lookup2(net, INADDR_ANY, sport, | 475 | result = udp4_lib_lookup2(net, saddr, sport, |
476 | daddr, hnum, dif, | 476 | INADDR_ANY, hnum, dif, |
477 | hslot2, slot2); | 477 | hslot2, slot2); |
478 | } | 478 | } |
479 | rcu_read_unlock(); | 479 | rcu_read_unlock(); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 16c4391f952b..65f9c379df38 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -108,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) | |||
108 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 108 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
109 | WARN_ON(!skb_dst(newskb)); | 109 | WARN_ON(!skb_dst(newskb)); |
110 | 110 | ||
111 | netif_rx(newskb); | 111 | netif_rx_ni(newskb); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index c177aea88c0b..90824852f598 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -259,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
259 | if (hslot->count < hslot2->count) | 259 | if (hslot->count < hslot2->count) |
260 | goto begin; | 260 | goto begin; |
261 | 261 | ||
262 | result = udp6_lib_lookup2(net, &in6addr_any, sport, | 262 | result = udp6_lib_lookup2(net, saddr, sport, |
263 | daddr, hnum, dif, | 263 | &in6addr_any, hnum, dif, |
264 | hslot2, slot2); | 264 | hslot2, slot2); |
265 | } | 265 | } |
266 | rcu_read_unlock(); | 266 | rcu_read_unlock(); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 06c33b68d8e5..b887e484ae04 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
225 | switch (sdata->vif.type) { | 225 | switch (sdata->vif.type) { |
226 | case NL80211_IFTYPE_AP: | 226 | case NL80211_IFTYPE_AP: |
227 | sdata->vif.bss_conf.enable_beacon = | 227 | sdata->vif.bss_conf.enable_beacon = |
228 | !!rcu_dereference(sdata->u.ap.beacon); | 228 | !!sdata->u.ap.beacon; |
229 | break; | 229 | break; |
230 | case NL80211_IFTYPE_ADHOC: | 230 | case NL80211_IFTYPE_ADHOC: |
231 | sdata->vif.bss_conf.enable_beacon = | 231 | sdata->vif.bss_conf.enable_beacon = |
232 | !!rcu_dereference(sdata->u.ibss.presp); | 232 | !!sdata->u.ibss.presp; |
233 | break; | 233 | break; |
234 | case NL80211_IFTYPE_MESH_POINT: | 234 | case NL80211_IFTYPE_MESH_POINT: |
235 | sdata->vif.bss_conf.enable_beacon = true; | 235 | sdata->vif.bss_conf.enable_beacon = true; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 58e3e3a61d99..859ee5f3d941 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -750,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
750 | 750 | ||
751 | switch (fc & IEEE80211_FCTL_STYPE) { | 751 | switch (fc & IEEE80211_FCTL_STYPE) { |
752 | case IEEE80211_STYPE_ACTION: | 752 | case IEEE80211_STYPE_ACTION: |
753 | if (skb->len < IEEE80211_MIN_ACTION_SIZE) | ||
754 | return RX_DROP_MONITOR; | ||
755 | /* fall through */ | ||
756 | case IEEE80211_STYPE_PROBE_RESP: | 753 | case IEEE80211_STYPE_PROBE_RESP: |
757 | case IEEE80211_STYPE_BEACON: | 754 | case IEEE80211_STYPE_BEACON: |
758 | skb_queue_tail(&ifmsh->skb_queue, skb); | 755 | skb_queue_tail(&ifmsh->skb_queue, skb); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f0accf622cd7..04ea07f0e78a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1974,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1974 | goto handled; | 1974 | goto handled; |
1975 | } | 1975 | } |
1976 | break; | 1976 | break; |
1977 | case MESH_PLINK_CATEGORY: | ||
1978 | case MESH_PATH_SEL_CATEGORY: | ||
1979 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
1980 | return ieee80211_mesh_rx_mgmt(sdata, rx->skb); | ||
1981 | break; | ||
1977 | } | 1982 | } |
1978 | 1983 | ||
1979 | /* | 1984 | /* |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 56422d894351..fb12cec4d333 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
93 | struct ieee80211_local *local = sdata->local; | 93 | struct ieee80211_local *local = sdata->local; |
94 | struct sta_info *sta; | 94 | struct sta_info *sta; |
95 | 95 | ||
96 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 96 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
97 | rcu_read_lock_held() || | ||
98 | lockdep_is_held(&local->sta_lock) || | ||
99 | lockdep_is_held(&local->sta_mtx)); | ||
97 | while (sta) { | 100 | while (sta) { |
98 | if (sta->sdata == sdata && | 101 | if (sta->sdata == sdata && |
99 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 102 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
100 | break; | 103 | break; |
101 | sta = rcu_dereference(sta->hnext); | 104 | sta = rcu_dereference_check(sta->hnext, |
105 | rcu_read_lock_held() || | ||
106 | lockdep_is_held(&local->sta_lock) || | ||
107 | lockdep_is_held(&local->sta_mtx)); | ||
102 | } | 108 | } |
103 | return sta; | 109 | return sta; |
104 | } | 110 | } |
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
113 | struct ieee80211_local *local = sdata->local; | 119 | struct ieee80211_local *local = sdata->local; |
114 | struct sta_info *sta; | 120 | struct sta_info *sta; |
115 | 121 | ||
116 | sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); | 122 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
123 | rcu_read_lock_held() || | ||
124 | lockdep_is_held(&local->sta_lock) || | ||
125 | lockdep_is_held(&local->sta_mtx)); | ||
117 | while (sta) { | 126 | while (sta) { |
118 | if ((sta->sdata == sdata || | 127 | if ((sta->sdata == sdata || |
119 | sta->sdata->bss == sdata->bss) && | 128 | sta->sdata->bss == sdata->bss) && |
120 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
121 | break; | 130 | break; |
122 | sta = rcu_dereference(sta->hnext); | 131 | sta = rcu_dereference_check(sta->hnext, |
132 | rcu_read_lock_held() || | ||
133 | lockdep_is_held(&local->sta_lock) || | ||
134 | lockdep_is_held(&local->sta_mtx)); | ||
123 | } | 135 | } |
124 | return sta; | 136 | return sta; |
125 | } | 137 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index cc90363d7e7a..243946d4809d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2169,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
2169 | case SIOCGIFDSTADDR: | 2169 | case SIOCGIFDSTADDR: |
2170 | case SIOCSIFDSTADDR: | 2170 | case SIOCSIFDSTADDR: |
2171 | case SIOCSIFFLAGS: | 2171 | case SIOCSIFFLAGS: |
2172 | if (!net_eq(sock_net(sk), &init_net)) | ||
2173 | return -ENOIOCTLCMD; | ||
2174 | return inet_dgram_ops.ioctl(sock, cmd, arg); | 2172 | return inet_dgram_ops.ioctl(sock, cmd, arg); |
2175 | #endif | 2173 | #endif |
2176 | 2174 | ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index fd90eb89842b..edea15a54e51 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
@@ -679,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, | |||
679 | int ret; | 679 | int ret; |
680 | 680 | ||
681 | dprintk("svcrdma: Creating RDMA socket\n"); | 681 | dprintk("svcrdma: Creating RDMA socket\n"); |
682 | 682 | if (sa->sa_family != AF_INET) { | |
683 | dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family); | ||
684 | return ERR_PTR(-EAFNOSUPPORT); | ||
685 | } | ||
683 | cma_xprt = rdma_create_xprt(serv, 1); | 686 | cma_xprt = rdma_create_xprt(serv, 1); |
684 | if (!cma_xprt) | 687 | if (!cma_xprt) |
685 | return ERR_PTR(-ENOMEM); | 688 | return ERR_PTR(-ENOMEM); |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index e56f711baccc..cbddd0cb83f1 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -83,6 +83,41 @@ struct compat_x25_subscrip_struct { | |||
83 | }; | 83 | }; |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | |||
87 | int x25_parse_address_block(struct sk_buff *skb, | ||
88 | struct x25_address *called_addr, | ||
89 | struct x25_address *calling_addr) | ||
90 | { | ||
91 | unsigned char len; | ||
92 | int needed; | ||
93 | int rc; | ||
94 | |||
95 | if (skb->len < 1) { | ||
96 | /* packet has no address block */ | ||
97 | rc = 0; | ||
98 | goto empty; | ||
99 | } | ||
100 | |||
101 | len = *skb->data; | ||
102 | needed = 1 + (len >> 4) + (len & 0x0f); | ||
103 | |||
104 | if (skb->len < needed) { | ||
105 | /* packet is too short to hold the addresses it claims | ||
106 | to hold */ | ||
107 | rc = -1; | ||
108 | goto empty; | ||
109 | } | ||
110 | |||
111 | return x25_addr_ntoa(skb->data, called_addr, calling_addr); | ||
112 | |||
113 | empty: | ||
114 | *called_addr->x25_addr = 0; | ||
115 | *calling_addr->x25_addr = 0; | ||
116 | |||
117 | return rc; | ||
118 | } | ||
119 | |||
120 | |||
86 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, | 121 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, |
87 | struct x25_address *calling_addr) | 122 | struct x25_address *calling_addr) |
88 | { | 123 | { |
@@ -554,7 +589,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol, | |||
554 | x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; | 589 | x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE; |
555 | x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; | 590 | x25->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE; |
556 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; | 591 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; |
557 | x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; | 592 | x25->facilities.throughput = 0; /* by default don't negotiate |
593 | throughput */ | ||
558 | x25->facilities.reverse = X25_DEFAULT_REVERSE; | 594 | x25->facilities.reverse = X25_DEFAULT_REVERSE; |
559 | x25->dte_facilities.calling_len = 0; | 595 | x25->dte_facilities.calling_len = 0; |
560 | x25->dte_facilities.called_len = 0; | 596 | x25->dte_facilities.called_len = 0; |
@@ -922,16 +958,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
922 | /* | 958 | /* |
923 | * Extract the X.25 addresses and convert them to ASCII strings, | 959 | * Extract the X.25 addresses and convert them to ASCII strings, |
924 | * and remove them. | 960 | * and remove them. |
961 | * | ||
962 | * Address block is mandatory in call request packets | ||
925 | */ | 963 | */ |
926 | addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr); | 964 | addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr); |
965 | if (addr_len <= 0) | ||
966 | goto out_clear_request; | ||
927 | skb_pull(skb, addr_len); | 967 | skb_pull(skb, addr_len); |
928 | 968 | ||
929 | /* | 969 | /* |
930 | * Get the length of the facilities, skip past them for the moment | 970 | * Get the length of the facilities, skip past them for the moment |
931 | * get the call user data because this is needed to determine | 971 | * get the call user data because this is needed to determine |
932 | * the correct listener | 972 | * the correct listener |
973 | * | ||
974 | * Facilities length is mandatory in call request packets | ||
933 | */ | 975 | */ |
976 | if (skb->len < 1) | ||
977 | goto out_clear_request; | ||
934 | len = skb->data[0] + 1; | 978 | len = skb->data[0] + 1; |
979 | if (skb->len < len) | ||
980 | goto out_clear_request; | ||
935 | skb_pull(skb,len); | 981 | skb_pull(skb,len); |
936 | 982 | ||
937 | /* | 983 | /* |
@@ -1415,9 +1461,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1415 | if (facilities.winsize_in < 1 || | 1461 | if (facilities.winsize_in < 1 || |
1416 | facilities.winsize_in > 127) | 1462 | facilities.winsize_in > 127) |
1417 | break; | 1463 | break; |
1418 | if (facilities.throughput < 0x03 || | 1464 | if (facilities.throughput) { |
1419 | facilities.throughput > 0xDD) | 1465 | int out = facilities.throughput & 0xf0; |
1420 | break; | 1466 | int in = facilities.throughput & 0x0f; |
1467 | if (!out) | ||
1468 | facilities.throughput |= | ||
1469 | X25_DEFAULT_THROUGHPUT << 4; | ||
1470 | else if (out < 0x30 || out > 0xD0) | ||
1471 | break; | ||
1472 | if (!in) | ||
1473 | facilities.throughput |= | ||
1474 | X25_DEFAULT_THROUGHPUT; | ||
1475 | else if (in < 0x03 || in > 0x0D) | ||
1476 | break; | ||
1477 | } | ||
1421 | if (facilities.reverse && | 1478 | if (facilities.reverse && |
1422 | (facilities.reverse & 0x81) != 0x81) | 1479 | (facilities.reverse & 0x81) != 0x81) |
1423 | break; | 1480 | break; |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index a21f6646eb3a..771bab00754b 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) | 35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
36 | { | 36 | { |
37 | unsigned char *p = skb->data; | 37 | unsigned char *p = skb->data; |
38 | unsigned int len = *p++; | 38 | unsigned int len; |
39 | 39 | ||
40 | *vc_fac_mask = 0; | 40 | *vc_fac_mask = 0; |
41 | 41 | ||
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); | 50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); |
51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); | 51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); |
52 | 52 | ||
53 | if (skb->len < 1) | ||
54 | return 0; | ||
55 | |||
56 | len = *p++; | ||
57 | |||
58 | if (len >= skb->len) | ||
59 | return -1; | ||
60 | |||
53 | while (len > 0) { | 61 | while (len > 0) { |
54 | switch (*p & X25_FAC_CLASS_MASK) { | 62 | switch (*p & X25_FAC_CLASS_MASK) { |
55 | case X25_FAC_CLASS_A: | 63 | case X25_FAC_CLASS_A: |
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
247 | memcpy(new, ours, sizeof(*new)); | 255 | memcpy(new, ours, sizeof(*new)); |
248 | 256 | ||
249 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); | 257 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); |
258 | if (len < 0) | ||
259 | return len; | ||
250 | 260 | ||
251 | /* | 261 | /* |
252 | * They want reverse charging, we won't accept it. | 262 | * They want reverse charging, we won't accept it. |
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
259 | new->reverse = theirs.reverse; | 269 | new->reverse = theirs.reverse; |
260 | 270 | ||
261 | if (theirs.throughput) { | 271 | if (theirs.throughput) { |
262 | if (theirs.throughput < ours->throughput) { | 272 | int theirs_in = theirs.throughput & 0x0f; |
263 | SOCK_DEBUG(sk, "X.25: throughput negotiated down\n"); | 273 | int theirs_out = theirs.throughput & 0xf0; |
264 | new->throughput = theirs.throughput; | 274 | int ours_in = ours->throughput & 0x0f; |
275 | int ours_out = ours->throughput & 0xf0; | ||
276 | if (!ours_in || theirs_in < ours_in) { | ||
277 | SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n"); | ||
278 | new->throughput = (new->throughput & 0xf0) | theirs_in; | ||
279 | } | ||
280 | if (!ours_out || theirs_out < ours_out) { | ||
281 | SOCK_DEBUG(sk, | ||
282 | "X.25: outbound throughput negotiated\n"); | ||
283 | new->throughput = (new->throughput & 0x0f) | theirs_out; | ||
265 | } | 284 | } |
266 | } | 285 | } |
267 | 286 | ||
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index a31b3b9e5966..372ac226e648 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -90,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) | |||
90 | static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) | 90 | static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) |
91 | { | 91 | { |
92 | struct x25_address source_addr, dest_addr; | 92 | struct x25_address source_addr, dest_addr; |
93 | int len; | ||
93 | 94 | ||
94 | switch (frametype) { | 95 | switch (frametype) { |
95 | case X25_CALL_ACCEPTED: { | 96 | case X25_CALL_ACCEPTED: { |
@@ -107,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
107 | * Parse the data in the frame. | 108 | * Parse the data in the frame. |
108 | */ | 109 | */ |
109 | skb_pull(skb, X25_STD_MIN_LEN); | 110 | skb_pull(skb, X25_STD_MIN_LEN); |
110 | skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); | 111 | |
111 | skb_pull(skb, | 112 | len = x25_parse_address_block(skb, &source_addr, |
112 | x25_parse_facilities(skb, &x25->facilities, | 113 | &dest_addr); |
114 | if (len > 0) | ||
115 | skb_pull(skb, len); | ||
116 | |||
117 | len = x25_parse_facilities(skb, &x25->facilities, | ||
113 | &x25->dte_facilities, | 118 | &x25->dte_facilities, |
114 | &x25->vc_facil_mask)); | 119 | &x25->vc_facil_mask); |
120 | if (len > 0) | ||
121 | skb_pull(skb, len); | ||
115 | /* | 122 | /* |
116 | * Copy any Call User Data. | 123 | * Copy any Call User Data. |
117 | */ | 124 | */ |
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 8da6a8428086..cd4f734e2749 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h | |||
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified | |||
82 | void avtab_cache_init(void); | 82 | void avtab_cache_init(void); |
83 | void avtab_cache_destroy(void); | 83 | void avtab_cache_destroy(void); |
84 | 84 | ||
85 | #define MAX_AVTAB_HASH_BITS 13 | 85 | #define MAX_AVTAB_HASH_BITS 11 |
86 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) | 86 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) |
87 | #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) | 87 | #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) |
88 | #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS | 88 | #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 656e474dca47..91acc9a243ec 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) | |||
863 | struct snd_ac97 *ac97; | 863 | struct snd_ac97 *ac97; |
864 | int ret; | 864 | int ret; |
865 | 865 | ||
866 | writel(0, aaci->base + AC97_POWERDOWN); | ||
867 | /* | 866 | /* |
868 | * Assert AACIRESET for 2us | 867 | * Assert AACIRESET for 2us |
869 | */ | 868 | */ |
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) | |||
1047 | 1046 | ||
1048 | writel(0x1fff, aaci->base + AACI_INTCLR); | 1047 | writel(0x1fff, aaci->base + AACI_INTCLR); |
1049 | writel(aaci->maincr, aaci->base + AACI_MAINCR); | 1048 | writel(aaci->maincr, aaci->base + AACI_MAINCR); |
1050 | 1049 | /* | |
1050 | * Fix: ac97 read back fail errors by reading | ||
1051 | * from any arbitrary aaci register. | ||
1052 | */ | ||
1053 | readl(aaci->base + AACI_CSCH1); | ||
1051 | ret = aaci_probe_ac97(aaci); | 1054 | ret = aaci_probe_ac97(aaci); |
1052 | if (ret) | 1055 | if (ret) |
1053 | goto out; | 1056 | goto out; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index f8fd586ae024..f669442b7c82 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2272,6 +2272,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { | |||
2272 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2272 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2273 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2273 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
2274 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | 2274 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), |
2275 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), | ||
2275 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), | 2276 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), |
2276 | {} | 2277 | {} |
2277 | }; | 2278 | }; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c7730dbb9ddb..aad1627f56f1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -230,6 +230,7 @@ enum { | |||
230 | ALC888_ACER_ASPIRE_7730G, | 230 | ALC888_ACER_ASPIRE_7730G, |
231 | ALC883_MEDION, | 231 | ALC883_MEDION, |
232 | ALC883_MEDION_MD2, | 232 | ALC883_MEDION_MD2, |
233 | ALC883_MEDION_WIM2160, | ||
233 | ALC883_LAPTOP_EAPD, | 234 | ALC883_LAPTOP_EAPD, |
234 | ALC883_LENOVO_101E_2ch, | 235 | ALC883_LENOVO_101E_2ch, |
235 | ALC883_LENOVO_NB0763, | 236 | ALC883_LENOVO_NB0763, |
@@ -1389,22 +1390,31 @@ struct alc_fixup { | |||
1389 | 1390 | ||
1390 | static void alc_pick_fixup(struct hda_codec *codec, | 1391 | static void alc_pick_fixup(struct hda_codec *codec, |
1391 | const struct snd_pci_quirk *quirk, | 1392 | const struct snd_pci_quirk *quirk, |
1392 | const struct alc_fixup *fix) | 1393 | const struct alc_fixup *fix, |
1394 | int pre_init) | ||
1393 | { | 1395 | { |
1394 | const struct alc_pincfg *cfg; | 1396 | const struct alc_pincfg *cfg; |
1395 | 1397 | ||
1396 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 1398 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
1397 | if (!quirk) | 1399 | if (!quirk) |
1398 | return; | 1400 | return; |
1399 | |||
1400 | fix += quirk->value; | 1401 | fix += quirk->value; |
1401 | cfg = fix->pins; | 1402 | cfg = fix->pins; |
1402 | if (cfg) { | 1403 | if (pre_init && cfg) { |
1404 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1405 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", | ||
1406 | codec->chip_name, quirk->name); | ||
1407 | #endif | ||
1403 | for (; cfg->nid; cfg++) | 1408 | for (; cfg->nid; cfg++) |
1404 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); | 1409 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); |
1405 | } | 1410 | } |
1406 | if (fix->verbs) | 1411 | if (!pre_init && fix->verbs) { |
1412 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1413 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", | ||
1414 | codec->chip_name, quirk->name); | ||
1415 | #endif | ||
1407 | add_verb(codec->spec, fix->verbs); | 1416 | add_verb(codec->spec, fix->verbs); |
1417 | } | ||
1408 | } | 1418 | } |
1409 | 1419 | ||
1410 | static int alc_read_coef_idx(struct hda_codec *codec, | 1420 | static int alc_read_coef_idx(struct hda_codec *codec, |
@@ -4808,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
4808 | } | 4818 | } |
4809 | } | 4819 | } |
4810 | 4820 | ||
4821 | static void alc880_auto_init_input_src(struct hda_codec *codec) | ||
4822 | { | ||
4823 | struct alc_spec *spec = codec->spec; | ||
4824 | int c; | ||
4825 | |||
4826 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
4827 | unsigned int mux_idx; | ||
4828 | const struct hda_input_mux *imux; | ||
4829 | mux_idx = c >= spec->num_mux_defs ? 0 : c; | ||
4830 | imux = &spec->input_mux[mux_idx]; | ||
4831 | if (!imux->num_items && mux_idx > 0) | ||
4832 | imux = &spec->input_mux[0]; | ||
4833 | if (imux) | ||
4834 | snd_hda_codec_write(codec, spec->adc_nids[c], 0, | ||
4835 | AC_VERB_SET_CONNECT_SEL, | ||
4836 | imux->items[0].index); | ||
4837 | } | ||
4838 | } | ||
4839 | |||
4811 | /* parse the BIOS configuration and set up the alc_spec */ | 4840 | /* parse the BIOS configuration and set up the alc_spec */ |
4812 | /* return 1 if successful, 0 if the proper config is not found, | 4841 | /* return 1 if successful, 0 if the proper config is not found, |
4813 | * or a negative error code | 4842 | * or a negative error code |
@@ -4886,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
4886 | alc880_auto_init_multi_out(codec); | 4915 | alc880_auto_init_multi_out(codec); |
4887 | alc880_auto_init_extra_out(codec); | 4916 | alc880_auto_init_extra_out(codec); |
4888 | alc880_auto_init_analog_input(codec); | 4917 | alc880_auto_init_analog_input(codec); |
4918 | alc880_auto_init_input_src(codec); | ||
4889 | if (spec->unsol_event) | 4919 | if (spec->unsol_event) |
4890 | alc_inithook(codec); | 4920 | alc_inithook(codec); |
4891 | } | 4921 | } |
@@ -6397,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
6397 | } | 6427 | } |
6398 | } | 6428 | } |
6399 | 6429 | ||
6430 | #define alc260_auto_init_input_src alc880_auto_init_input_src | ||
6431 | |||
6400 | /* | 6432 | /* |
6401 | * generic initialization of ADC, input mixers and output mixers | 6433 | * generic initialization of ADC, input mixers and output mixers |
6402 | */ | 6434 | */ |
@@ -6483,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
6483 | struct alc_spec *spec = codec->spec; | 6515 | struct alc_spec *spec = codec->spec; |
6484 | alc260_auto_init_multi_out(codec); | 6516 | alc260_auto_init_multi_out(codec); |
6485 | alc260_auto_init_analog_input(codec); | 6517 | alc260_auto_init_analog_input(codec); |
6518 | alc260_auto_init_input_src(codec); | ||
6486 | if (spec->unsol_event) | 6519 | if (spec->unsol_event) |
6487 | alc_inithook(codec); | 6520 | alc_inithook(codec); |
6488 | } | 6521 | } |
@@ -8455,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { | |||
8455 | { } /* end */ | 8488 | { } /* end */ |
8456 | }; | 8489 | }; |
8457 | 8490 | ||
8491 | static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { | ||
8492 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
8493 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8494 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
8495 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), | ||
8496 | HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), | ||
8497 | HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), | ||
8498 | { } /* end */ | ||
8499 | }; | ||
8500 | |||
8501 | static struct hda_verb alc883_medion_wim2160_verbs[] = { | ||
8502 | /* Unmute front mixer */ | ||
8503 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8504 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8505 | |||
8506 | /* Set speaker pin to front mixer */ | ||
8507 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8508 | |||
8509 | /* Init headphone pin */ | ||
8510 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
8511 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8512 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8513 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8514 | |||
8515 | { } /* end */ | ||
8516 | }; | ||
8517 | |||
8518 | /* toggle speaker-output according to the hp-jack state */ | ||
8519 | static void alc883_medion_wim2160_setup(struct hda_codec *codec) | ||
8520 | { | ||
8521 | struct alc_spec *spec = codec->spec; | ||
8522 | |||
8523 | spec->autocfg.hp_pins[0] = 0x1a; | ||
8524 | spec->autocfg.speaker_pins[0] = 0x15; | ||
8525 | } | ||
8526 | |||
8458 | static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | 8527 | static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { |
8459 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8528 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8460 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8529 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -9164,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
9164 | [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", | 9233 | [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", |
9165 | [ALC883_MEDION] = "medion", | 9234 | [ALC883_MEDION] = "medion", |
9166 | [ALC883_MEDION_MD2] = "medion-md2", | 9235 | [ALC883_MEDION_MD2] = "medion-md2", |
9236 | [ALC883_MEDION_WIM2160] = "medion-wim2160", | ||
9167 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", | 9237 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
9168 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", | 9238 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", |
9169 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", | 9239 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", |
@@ -9280,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
9280 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), | 9350 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), |
9281 | 9351 | ||
9282 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), | 9352 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), |
9353 | SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), | ||
9283 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), | 9354 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), |
9284 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), | 9355 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), |
9285 | SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), | 9356 | SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), |
@@ -9818,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = { | |||
9818 | .setup = alc883_medion_md2_setup, | 9889 | .setup = alc883_medion_md2_setup, |
9819 | .init_hook = alc_automute_amp, | 9890 | .init_hook = alc_automute_amp, |
9820 | }, | 9891 | }, |
9892 | [ALC883_MEDION_WIM2160] = { | ||
9893 | .mixers = { alc883_medion_wim2160_mixer }, | ||
9894 | .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, | ||
9895 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9896 | .dac_nids = alc883_dac_nids, | ||
9897 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9898 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
9899 | .adc_nids = alc883_adc_nids, | ||
9900 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
9901 | .channel_mode = alc883_3ST_2ch_modes, | ||
9902 | .input_mux = &alc883_capture_source, | ||
9903 | .unsol_event = alc_automute_amp_unsol_event, | ||
9904 | .setup = alc883_medion_wim2160_setup, | ||
9905 | .init_hook = alc_automute_amp, | ||
9906 | }, | ||
9821 | [ALC883_LAPTOP_EAPD] = { | 9907 | [ALC883_LAPTOP_EAPD] = { |
9822 | .mixers = { alc883_base_mixer }, | 9908 | .mixers = { alc883_base_mixer }, |
9823 | .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, | 9909 | .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, |
@@ -10363,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
10363 | board_config = ALC882_AUTO; | 10449 | board_config = ALC882_AUTO; |
10364 | } | 10450 | } |
10365 | 10451 | ||
10366 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); | 10452 | if (board_config == ALC882_AUTO) |
10453 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); | ||
10367 | 10454 | ||
10368 | if (board_config == ALC882_AUTO) { | 10455 | if (board_config == ALC882_AUTO) { |
10369 | /* automatic parse from the BIOS config */ | 10456 | /* automatic parse from the BIOS config */ |
@@ -10436,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
10436 | set_capture_mixer(codec); | 10523 | set_capture_mixer(codec); |
10437 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 10524 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
10438 | 10525 | ||
10526 | if (board_config == ALC882_AUTO) | ||
10527 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); | ||
10528 | |||
10439 | spec->vmaster_nid = 0x0c; | 10529 | spec->vmaster_nid = 0x0c; |
10440 | 10530 | ||
10441 | codec->patch_ops = alc_patch_ops; | 10531 | codec->patch_ops = alc_patch_ops; |
@@ -12816,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12816 | dac = 0x02; | 12906 | dac = 0x02; |
12817 | break; | 12907 | break; |
12818 | case 0x15: | 12908 | case 0x15: |
12909 | case 0x21: /* ALC269vb has this pin, too */ | ||
12819 | dac = 0x03; | 12910 | dac = 0x03; |
12820 | break; | 12911 | break; |
12821 | default: | 12912 | default: |
@@ -13735,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec, | |||
13735 | } | 13826 | } |
13736 | } | 13827 | } |
13737 | 13828 | ||
13738 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) | 13829 | static void alc269_laptop_amic_setup(struct hda_codec *codec) |
13739 | { | 13830 | { |
13740 | struct alc_spec *spec = codec->spec; | 13831 | struct alc_spec *spec = codec->spec; |
13741 | spec->autocfg.hp_pins[0] = 0x15; | 13832 | spec->autocfg.hp_pins[0] = 0x15; |
13742 | spec->autocfg.speaker_pins[0] = 0x14; | 13833 | spec->autocfg.speaker_pins[0] = 0x14; |
13743 | spec->ext_mic.pin = 0x18; | 13834 | spec->ext_mic.pin = 0x18; |
13744 | spec->ext_mic.mux_idx = 0; | 13835 | spec->ext_mic.mux_idx = 0; |
13745 | spec->int_mic.pin = 0x12; | 13836 | spec->int_mic.pin = 0x19; |
13746 | spec->int_mic.mux_idx = 5; | 13837 | spec->int_mic.mux_idx = 1; |
13747 | spec->auto_mic = 1; | 13838 | spec->auto_mic = 1; |
13748 | } | 13839 | } |
13749 | 13840 | ||
13750 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | 13841 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) |
13751 | { | 13842 | { |
13752 | struct alc_spec *spec = codec->spec; | 13843 | struct alc_spec *spec = codec->spec; |
13753 | spec->autocfg.hp_pins[0] = 0x15; | 13844 | spec->autocfg.hp_pins[0] = 0x15; |
@@ -13755,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | |||
13755 | spec->ext_mic.pin = 0x18; | 13846 | spec->ext_mic.pin = 0x18; |
13756 | spec->ext_mic.mux_idx = 0; | 13847 | spec->ext_mic.mux_idx = 0; |
13757 | spec->int_mic.pin = 0x12; | 13848 | spec->int_mic.pin = 0x12; |
13758 | spec->int_mic.mux_idx = 6; | 13849 | spec->int_mic.mux_idx = 5; |
13759 | spec->auto_mic = 1; | 13850 | spec->auto_mic = 1; |
13760 | } | 13851 | } |
13761 | 13852 | ||
13762 | static void alc269_laptop_amic_setup(struct hda_codec *codec) | 13853 | static void alc269vb_laptop_amic_setup(struct hda_codec *codec) |
13763 | { | 13854 | { |
13764 | struct alc_spec *spec = codec->spec; | 13855 | struct alc_spec *spec = codec->spec; |
13765 | spec->autocfg.hp_pins[0] = 0x15; | 13856 | spec->autocfg.hp_pins[0] = 0x21; |
13766 | spec->autocfg.speaker_pins[0] = 0x14; | 13857 | spec->autocfg.speaker_pins[0] = 0x14; |
13767 | spec->ext_mic.pin = 0x18; | 13858 | spec->ext_mic.pin = 0x18; |
13768 | spec->ext_mic.mux_idx = 0; | 13859 | spec->ext_mic.mux_idx = 0; |
@@ -13771,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec) | |||
13771 | spec->auto_mic = 1; | 13862 | spec->auto_mic = 1; |
13772 | } | 13863 | } |
13773 | 13864 | ||
13865 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | ||
13866 | { | ||
13867 | struct alc_spec *spec = codec->spec; | ||
13868 | spec->autocfg.hp_pins[0] = 0x21; | ||
13869 | spec->autocfg.speaker_pins[0] = 0x14; | ||
13870 | spec->ext_mic.pin = 0x18; | ||
13871 | spec->ext_mic.mux_idx = 0; | ||
13872 | spec->int_mic.pin = 0x12; | ||
13873 | spec->int_mic.mux_idx = 6; | ||
13874 | spec->auto_mic = 1; | ||
13875 | } | ||
13876 | |||
13774 | static void alc269_laptop_inithook(struct hda_codec *codec) | 13877 | static void alc269_laptop_inithook(struct hda_codec *codec) |
13775 | { | 13878 | { |
13776 | alc269_speaker_automute(codec); | 13879 | alc269_speaker_automute(codec); |
@@ -13975,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
13975 | alc_inithook(codec); | 14078 | alc_inithook(codec); |
13976 | } | 14079 | } |
13977 | 14080 | ||
14081 | enum { | ||
14082 | ALC269_FIXUP_SONY_VAIO, | ||
14083 | }; | ||
14084 | |||
14085 | const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { | ||
14086 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, | ||
14087 | {} | ||
14088 | }; | ||
14089 | |||
14090 | static const struct alc_fixup alc269_fixups[] = { | ||
14091 | [ALC269_FIXUP_SONY_VAIO] = { | ||
14092 | .verbs = alc269_sony_vaio_fixup_verbs | ||
14093 | }, | ||
14094 | }; | ||
14095 | |||
14096 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | ||
14097 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | ||
14098 | {} | ||
14099 | }; | ||
14100 | |||
14101 | |||
13978 | /* | 14102 | /* |
13979 | * configuration and preset | 14103 | * configuration and preset |
13980 | */ | 14104 | */ |
@@ -14034,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { | |||
14034 | ALC269_DMIC), | 14158 | ALC269_DMIC), |
14035 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), | 14159 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), |
14036 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), | 14160 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), |
14037 | SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), | 14161 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), |
14038 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | 14162 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), |
14039 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), | 14163 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), |
14040 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | 14164 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), |
@@ -14108,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
14108 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 14232 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
14109 | .channel_mode = alc269_modes, | 14233 | .channel_mode = alc269_modes, |
14110 | .unsol_event = alc269_laptop_unsol_event, | 14234 | .unsol_event = alc269_laptop_unsol_event, |
14111 | .setup = alc269_laptop_amic_setup, | 14235 | .setup = alc269vb_laptop_amic_setup, |
14112 | .init_hook = alc269_laptop_inithook, | 14236 | .init_hook = alc269_laptop_inithook, |
14113 | }, | 14237 | }, |
14114 | [ALC269VB_DMIC] = { | 14238 | [ALC269VB_DMIC] = { |
@@ -14188,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec) | |||
14188 | board_config = ALC269_AUTO; | 14312 | board_config = ALC269_AUTO; |
14189 | } | 14313 | } |
14190 | 14314 | ||
14315 | if (board_config == ALC269_AUTO) | ||
14316 | alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); | ||
14317 | |||
14191 | if (board_config == ALC269_AUTO) { | 14318 | if (board_config == ALC269_AUTO) { |
14192 | /* automatic parse from the BIOS config */ | 14319 | /* automatic parse from the BIOS config */ |
14193 | err = alc269_parse_auto_config(codec); | 14320 | err = alc269_parse_auto_config(codec); |
@@ -14240,6 +14367,9 @@ static int patch_alc269(struct hda_codec *codec) | |||
14240 | set_capture_mixer(codec); | 14367 | set_capture_mixer(codec); |
14241 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 14368 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
14242 | 14369 | ||
14370 | if (board_config == ALC269_AUTO) | ||
14371 | alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); | ||
14372 | |||
14243 | spec->vmaster_nid = 0x02; | 14373 | spec->vmaster_nid = 0x02; |
14244 | 14374 | ||
14245 | codec->patch_ops = alc_patch_ops; | 14375 | codec->patch_ops = alc_patch_ops; |
@@ -15328,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
15328 | board_config = ALC861_AUTO; | 15458 | board_config = ALC861_AUTO; |
15329 | } | 15459 | } |
15330 | 15460 | ||
15331 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); | 15461 | if (board_config == ALC861_AUTO) |
15462 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); | ||
15332 | 15463 | ||
15333 | if (board_config == ALC861_AUTO) { | 15464 | if (board_config == ALC861_AUTO) { |
15334 | /* automatic parse from the BIOS config */ | 15465 | /* automatic parse from the BIOS config */ |
@@ -15365,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
15365 | 15496 | ||
15366 | spec->vmaster_nid = 0x03; | 15497 | spec->vmaster_nid = 0x03; |
15367 | 15498 | ||
15499 | if (board_config == ALC861_AUTO) | ||
15500 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); | ||
15501 | |||
15368 | codec->patch_ops = alc_patch_ops; | 15502 | codec->patch_ops = alc_patch_ops; |
15369 | if (board_config == ALC861_AUTO) { | 15503 | if (board_config == ALC861_AUTO) { |
15370 | spec->init_hook = alc861_auto_init; | 15504 | spec->init_hook = alc861_auto_init; |
@@ -16299,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
16299 | board_config = ALC861VD_AUTO; | 16433 | board_config = ALC861VD_AUTO; |
16300 | } | 16434 | } |
16301 | 16435 | ||
16302 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); | 16436 | if (board_config == ALC861VD_AUTO) |
16437 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); | ||
16303 | 16438 | ||
16304 | if (board_config == ALC861VD_AUTO) { | 16439 | if (board_config == ALC861VD_AUTO) { |
16305 | /* automatic parse from the BIOS config */ | 16440 | /* automatic parse from the BIOS config */ |
@@ -16347,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
16347 | 16482 | ||
16348 | spec->vmaster_nid = 0x02; | 16483 | spec->vmaster_nid = 0x02; |
16349 | 16484 | ||
16485 | if (board_config == ALC861VD_AUTO) | ||
16486 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); | ||
16487 | |||
16350 | codec->patch_ops = alc_patch_ops; | 16488 | codec->patch_ops = alc_patch_ops; |
16351 | 16489 | ||
16352 | if (board_config == ALC861VD_AUTO) | 16490 | if (board_config == ALC861VD_AUTO) |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9ddc37300f6b..73453814e098 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | |||
476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); | 476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); |
477 | if (!knew->name) | 477 | if (!knew->name) |
478 | return NULL; | 478 | return NULL; |
479 | return 0; | 479 | return knew; |
480 | } | 480 | } |
481 | 481 | ||
482 | static void via_free_kctls(struct hda_codec *codec) | 482 | static void via_free_kctls(struct hda_codec *codec) |
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = { | |||
1215 | }, | 1215 | }, |
1216 | }; | 1216 | }; |
1217 | 1217 | ||
1218 | static int via_hp_build(struct via_spec *spec) | 1218 | static int via_hp_build(struct hda_codec *codec) |
1219 | { | 1219 | { |
1220 | struct via_spec *spec = codec->spec; | ||
1220 | struct snd_kcontrol_new *knew; | 1221 | struct snd_kcontrol_new *knew; |
1221 | hda_nid_t nid; | 1222 | hda_nid_t nid; |
1222 | 1223 | int nums; | |
1223 | knew = via_clone_control(spec, &via_hp_mixer[0]); | 1224 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; |
1224 | if (knew == NULL) | ||
1225 | return -ENOMEM; | ||
1226 | 1225 | ||
1227 | switch (spec->codec_type) { | 1226 | switch (spec->codec_type) { |
1228 | case VT1718S: | 1227 | case VT1718S: |
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec) | |||
1239 | break; | 1238 | break; |
1240 | } | 1239 | } |
1241 | 1240 | ||
1241 | nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); | ||
1242 | if (nums <= 1) | ||
1243 | return 0; | ||
1244 | |||
1245 | knew = via_clone_control(spec, &via_hp_mixer[0]); | ||
1246 | if (knew == NULL) | ||
1247 | return -ENOMEM; | ||
1248 | |||
1242 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | 1249 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; |
1243 | knew->private_value = nid; | 1250 | knew->private_value = nid; |
1244 | 1251 | ||
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
2561 | spec->input_mux = &spec->private_imux[0]; | 2568 | spec->input_mux = &spec->private_imux[0]; |
2562 | 2569 | ||
2563 | if (spec->hp_mux) | 2570 | if (spec->hp_mux) |
2564 | via_hp_build(spec); | 2571 | via_hp_build(codec); |
2565 | 2572 | ||
2566 | via_smart51_build(spec); | 2573 | via_smart51_build(spec); |
2567 | return 1; | 2574 | return 1; |
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
3087 | spec->input_mux = &spec->private_imux[0]; | 3094 | spec->input_mux = &spec->private_imux[0]; |
3088 | 3095 | ||
3089 | if (spec->hp_mux) | 3096 | if (spec->hp_mux) |
3090 | via_hp_build(spec); | 3097 | via_hp_build(codec); |
3091 | 3098 | ||
3092 | via_smart51_build(spec); | 3099 | via_smart51_build(spec); |
3093 | return 1; | 3100 | return 1; |
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
3654 | spec->input_mux = &spec->private_imux[0]; | 3661 | spec->input_mux = &spec->private_imux[0]; |
3655 | 3662 | ||
3656 | if (spec->hp_mux) | 3663 | if (spec->hp_mux) |
3657 | via_hp_build(spec); | 3664 | via_hp_build(codec); |
3658 | 3665 | ||
3659 | via_smart51_build(spec); | 3666 | via_smart51_build(spec); |
3660 | return 1; | 3667 | return 1; |
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4140 | spec->input_mux = &spec->private_imux[0]; | 4147 | spec->input_mux = &spec->private_imux[0]; |
4141 | 4148 | ||
4142 | if (spec->hp_mux) | 4149 | if (spec->hp_mux) |
4143 | via_hp_build(spec); | 4150 | via_hp_build(codec); |
4144 | 4151 | ||
4145 | via_smart51_build(spec); | 4152 | via_smart51_build(spec); |
4146 | return 1; | 4153 | return 1; |
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
4510 | spec->input_mux = &spec->private_imux[0]; | 4517 | spec->input_mux = &spec->private_imux[0]; |
4511 | 4518 | ||
4512 | if (spec->hp_mux) | 4519 | if (spec->hp_mux) |
4513 | via_hp_build(spec); | 4520 | via_hp_build(codec); |
4514 | 4521 | ||
4515 | return 1; | 4522 | return 1; |
4516 | } | 4523 | } |
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) | |||
4930 | spec->input_mux = &spec->private_imux[0]; | 4937 | spec->input_mux = &spec->private_imux[0]; |
4931 | 4938 | ||
4932 | if (spec->hp_mux) | 4939 | if (spec->hp_mux) |
4933 | via_hp_build(spec); | 4940 | via_hp_build(codec); |
4934 | 4941 | ||
4935 | via_smart51_build(spec); | 4942 | via_smart51_build(spec); |
4936 | 4943 | ||
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) | |||
5425 | spec->input_mux = &spec->private_imux[0]; | 5432 | spec->input_mux = &spec->private_imux[0]; |
5426 | 5433 | ||
5427 | if (spec->hp_mux) | 5434 | if (spec->hp_mux) |
5428 | via_hp_build(spec); | 5435 | via_hp_build(codec); |
5429 | 5436 | ||
5430 | via_smart51_build(spec); | 5437 | via_smart51_build(spec); |
5431 | 5438 | ||
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) | |||
5781 | spec->input_mux = &spec->private_imux[0]; | 5788 | spec->input_mux = &spec->private_imux[0]; |
5782 | 5789 | ||
5783 | if (spec->hp_mux) | 5790 | if (spec->hp_mux) |
5784 | via_hp_build(spec); | 5791 | via_hp_build(codec); |
5785 | 5792 | ||
5786 | return 1; | 5793 | return 1; |
5787 | } | 5794 | } |
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec, | |||
6000 | 6007 | ||
6001 | /* Line-Out: PortE */ | 6008 | /* Line-Out: PortE */ |
6002 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, | 6009 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, |
6003 | "Master Front Playback Volume", | 6010 | "Front Playback Volume", |
6004 | HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); | 6011 | HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); |
6005 | if (err < 0) | 6012 | if (err < 0) |
6006 | return err; | 6013 | return err; |
6007 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, | 6014 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, |
6008 | "Master Front Playback Switch", | 6015 | "Front Playback Switch", |
6009 | HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); | 6016 | HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); |
6010 | if (err < 0) | 6017 | if (err < 0) |
6011 | return err; | 6018 | return err; |
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) | |||
6130 | spec->input_mux = &spec->private_imux[0]; | 6137 | spec->input_mux = &spec->private_imux[0]; |
6131 | 6138 | ||
6132 | if (spec->hp_mux) | 6139 | if (spec->hp_mux) |
6133 | via_hp_build(spec); | 6140 | via_hp_build(codec); |
6134 | 6141 | ||
6135 | return 1; | 6142 | return 1; |
6136 | } | 6143 | } |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index a34cbcf7904f..002e289d1255 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/version.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 2e79d7136298..2b31ac673ea4 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -71,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data) | |||
71 | 71 | ||
72 | static void snd_imx_dma_err_callback(int channel, void *data, int err) | 72 | static void snd_imx_dma_err_callback(int channel, void *data, int err) |
73 | { | 73 | { |
74 | pr_err("DMA error callback called\n"); | 74 | struct snd_pcm_substream *substream = data; |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
76 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
79 | int ret; | ||
75 | 80 | ||
76 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", | 81 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", |
77 | channel, | 82 | channel, |
@@ -79,6 +84,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
79 | err & IMX_DMA_ERR_REQUEST ? " request" : "", | 84 | err & IMX_DMA_ERR_REQUEST ? " request" : "", |
80 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", | 85 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", |
81 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); | 86 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); |
87 | |||
88 | imx_dma_disable(iprtd->dma); | ||
89 | ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, | ||
90 | IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, | ||
91 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
92 | DMA_MODE_WRITE : DMA_MODE_READ); | ||
93 | if (!ret) | ||
94 | imx_dma_enable(iprtd->dma); | ||
82 | } | 95 | } |
83 | 96 | ||
84 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 97 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index f96a373699cf..6b518e07eea9 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c | |||
@@ -39,23 +39,24 @@ struct imx_pcm_runtime_data { | |||
39 | unsigned long offset; | 39 | unsigned long offset; |
40 | unsigned long last_offset; | 40 | unsigned long last_offset; |
41 | unsigned long size; | 41 | unsigned long size; |
42 | struct timer_list timer; | 42 | struct hrtimer hrt; |
43 | int poll_time; | 43 | int poll_time_ns; |
44 | struct snd_pcm_substream *substream; | ||
45 | atomic_t running; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) | 48 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) |
47 | { | 49 | { |
48 | iprtd->timer.expires = jiffies + iprtd->poll_time; | 50 | struct imx_pcm_runtime_data *iprtd = |
49 | } | 51 | container_of(hrt, struct imx_pcm_runtime_data, hrt); |
50 | 52 | struct snd_pcm_substream *substream = iprtd->substream; | |
51 | static void imx_ssi_timer_callback(unsigned long data) | ||
52 | { | ||
53 | struct snd_pcm_substream *substream = (void *)data; | ||
54 | struct snd_pcm_runtime *runtime = substream->runtime; | 53 | struct snd_pcm_runtime *runtime = substream->runtime; |
55 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
56 | struct pt_regs regs; | 54 | struct pt_regs regs; |
57 | unsigned long delta; | 55 | unsigned long delta; |
58 | 56 | ||
57 | if (!atomic_read(&iprtd->running)) | ||
58 | return HRTIMER_NORESTART; | ||
59 | |||
59 | get_fiq_regs(®s); | 60 | get_fiq_regs(®s); |
60 | 61 | ||
61 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 62 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -72,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data) | |||
72 | 73 | ||
73 | /* If we've transferred at least a period then report it and | 74 | /* If we've transferred at least a period then report it and |
74 | * reset our poll time */ | 75 | * reset our poll time */ |
75 | if (delta >= runtime->period_size) { | 76 | if (delta >= iprtd->period) { |
76 | snd_pcm_period_elapsed(substream); | 77 | snd_pcm_period_elapsed(substream); |
77 | iprtd->last_offset = iprtd->offset; | 78 | iprtd->last_offset = iprtd->offset; |
78 | |||
79 | imx_ssi_set_next_poll(iprtd); | ||
80 | } | 79 | } |
81 | 80 | ||
82 | /* Restart the timer; if we didn't report we'll run on the next tick */ | 81 | hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); |
83 | add_timer(&iprtd->timer); | ||
84 | 82 | ||
83 | return HRTIMER_RESTART; | ||
85 | } | 84 | } |
86 | 85 | ||
87 | static struct fiq_handler fh = { | 86 | static struct fiq_handler fh = { |
@@ -99,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
99 | iprtd->period = params_period_bytes(params) ; | 98 | iprtd->period = params_period_bytes(params) ; |
100 | iprtd->offset = 0; | 99 | iprtd->offset = 0; |
101 | iprtd->last_offset = 0; | 100 | iprtd->last_offset = 0; |
102 | iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); | 101 | iprtd->poll_time_ns = 1000000000 / params_rate(params) * |
103 | 102 | params_period_size(params); | |
104 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 103 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
105 | 104 | ||
106 | return 0; | 105 | return 0; |
@@ -135,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
135 | case SNDRV_PCM_TRIGGER_START: | 134 | case SNDRV_PCM_TRIGGER_START: |
136 | case SNDRV_PCM_TRIGGER_RESUME: | 135 | case SNDRV_PCM_TRIGGER_RESUME: |
137 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 136 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
138 | imx_ssi_set_next_poll(iprtd); | 137 | atomic_set(&iprtd->running, 1); |
139 | add_timer(&iprtd->timer); | 138 | hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), |
139 | HRTIMER_MODE_REL); | ||
140 | if (++fiq_enable == 1) | 140 | if (++fiq_enable == 1) |
141 | enable_fiq(imx_pcm_fiq); | 141 | enable_fiq(imx_pcm_fiq); |
142 | 142 | ||
@@ -145,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
145 | case SNDRV_PCM_TRIGGER_STOP: | 145 | case SNDRV_PCM_TRIGGER_STOP: |
146 | case SNDRV_PCM_TRIGGER_SUSPEND: | 146 | case SNDRV_PCM_TRIGGER_SUSPEND: |
147 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 147 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
148 | del_timer(&iprtd->timer); | 148 | atomic_set(&iprtd->running, 0); |
149 | |||
149 | if (--fiq_enable == 0) | 150 | if (--fiq_enable == 0) |
150 | disable_fiq(imx_pcm_fiq); | 151 | disable_fiq(imx_pcm_fiq); |
151 | 152 | ||
152 | |||
153 | break; | 153 | break; |
154 | default: | 154 | default: |
155 | return -EINVAL; | 155 | return -EINVAL; |
@@ -180,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { | |||
180 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, | 180 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, |
181 | .period_bytes_min = 128, | 181 | .period_bytes_min = 128, |
182 | .period_bytes_max = 16 * 1024, | 182 | .period_bytes_max = 16 * 1024, |
183 | .periods_min = 2, | 183 | .periods_min = 4, |
184 | .periods_max = 255, | 184 | .periods_max = 255, |
185 | .fifo_size = 0, | 185 | .fifo_size = 0, |
186 | }; | 186 | }; |
@@ -194,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
194 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | 194 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); |
195 | runtime->private_data = iprtd; | 195 | runtime->private_data = iprtd; |
196 | 196 | ||
197 | init_timer(&iprtd->timer); | 197 | iprtd->substream = substream; |
198 | iprtd->timer.data = (unsigned long)substream; | 198 | |
199 | iprtd->timer.function = imx_ssi_timer_callback; | 199 | atomic_set(&iprtd->running, 0); |
200 | hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
201 | iprtd->hrt.function = snd_hrtimer_callback; | ||
200 | 202 | ||
201 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 203 | ret = snd_pcm_hw_constraint_integer(substream->runtime, |
202 | SNDRV_PCM_HW_PARAM_PERIODS); | 204 | SNDRV_PCM_HW_PARAM_PERIODS); |
@@ -212,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream) | |||
212 | struct snd_pcm_runtime *runtime = substream->runtime; | 214 | struct snd_pcm_runtime *runtime = substream->runtime; |
213 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 215 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
214 | 216 | ||
215 | del_timer_sync(&iprtd->timer); | 217 | hrtimer_cancel(&iprtd->hrt); |
218 | |||
216 | kfree(iprtd); | 219 | kfree(iprtd); |
217 | 220 | ||
218 | return 0; | 221 | return 0; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 0bcc6d7d9471..80b4fee2442b 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -656,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
656 | dai->private_data = ssi; | 656 | dai->private_data = ssi; |
657 | 657 | ||
658 | if ((cpu_is_mx27() || cpu_is_mx21()) && | 658 | if ((cpu_is_mx27() || cpu_is_mx21()) && |
659 | !(ssi->flags & IMX_SSI_USE_AC97)) { | 659 | !(ssi->flags & IMX_SSI_USE_AC97) && |
660 | (ssi->flags & IMX_SSI_DMA)) { | ||
660 | ssi->flags |= IMX_SSI_DMA; | 661 | ssi->flags |= IMX_SSI_DMA; |
661 | platform = imx_ssi_dma_mx2_init(pdev, ssi); | 662 | platform = imx_ssi_dma_mx2_init(pdev, ssi); |
662 | } else | 663 | } else |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 2c59afd99611..9e28b20cb2ce 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
986 | DEFINE_WAIT(wait); | 986 | DEFINE_WAIT(wait); |
987 | long timeout = msecs_to_jiffies(50); | 987 | long timeout = msecs_to_jiffies(50); |
988 | 988 | ||
989 | if (ep->umidi->disconnected) | ||
990 | return; | ||
989 | /* | 991 | /* |
990 | * The substream buffer is empty, but some data might still be in the | 992 | * The substream buffer is empty, but some data might still be in the |
991 | * currently active URBs, so we have to wait for those to complete. | 993 | * currently active URBs, so we have to wait for those to complete. |
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1123 | * Frees an output endpoint. | 1125 | * Frees an output endpoint. |
1124 | * May be called when ep hasn't been initialized completely. | 1126 | * May be called when ep hasn't been initialized completely. |
1125 | */ | 1127 | */ |
1126 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) | 1128 | static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) |
1127 | { | 1129 | { |
1128 | unsigned int i; | 1130 | unsigned int i; |
1129 | 1131 | ||
1130 | for (i = 0; i < OUTPUT_URBS; ++i) | 1132 | for (i = 0; i < OUTPUT_URBS; ++i) |
1131 | if (ep->urbs[i].urb) | 1133 | if (ep->urbs[i].urb) { |
1132 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, | 1134 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, |
1133 | ep->max_transfer); | 1135 | ep->max_transfer); |
1136 | ep->urbs[i].urb = NULL; | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) | ||
1141 | { | ||
1142 | snd_usbmidi_out_endpoint_clear(ep); | ||
1134 | kfree(ep); | 1143 | kfree(ep); |
1135 | } | 1144 | } |
1136 | 1145 | ||
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1262 | usb_kill_urb(ep->out->urbs[j].urb); | 1271 | usb_kill_urb(ep->out->urbs[j].urb); |
1263 | if (umidi->usb_protocol_ops->finish_out_endpoint) | 1272 | if (umidi->usb_protocol_ops->finish_out_endpoint) |
1264 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); | 1273 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); |
1274 | ep->out->active_urbs = 0; | ||
1275 | if (ep->out->drain_urbs) { | ||
1276 | ep->out->drain_urbs = 0; | ||
1277 | wake_up(&ep->out->drain_wait); | ||
1278 | } | ||
1265 | } | 1279 | } |
1266 | if (ep->in) | 1280 | if (ep->in) |
1267 | for (j = 0; j < INPUT_URBS; ++j) | 1281 | for (j = 0; j < INPUT_URBS; ++j) |
1268 | usb_kill_urb(ep->in->urbs[j]); | 1282 | usb_kill_urb(ep->in->urbs[j]); |
1269 | /* free endpoints here; later call can result in Oops */ | 1283 | /* free endpoints here; later call can result in Oops */ |
1270 | if (ep->out) { | 1284 | if (ep->out) |
1271 | snd_usbmidi_out_endpoint_delete(ep->out); | 1285 | snd_usbmidi_out_endpoint_clear(ep->out); |
1272 | ep->out = NULL; | ||
1273 | } | ||
1274 | if (ep->in) { | 1286 | if (ep->in) { |
1275 | snd_usbmidi_in_endpoint_delete(ep->in); | 1287 | snd_usbmidi_in_endpoint_delete(ep->in); |
1276 | ep->in = NULL; | 1288 | ep->in = NULL; |
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 02ff2b19dbe2..4d10b1e047f4 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -316,12 +316,16 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, | |||
316 | kvm_assigned_dev_intr, 0, | 316 | kvm_assigned_dev_intr, 0, |
317 | "kvm_assigned_msix_device", | 317 | "kvm_assigned_msix_device", |
318 | (void *)dev); | 318 | (void *)dev); |
319 | /* FIXME: free requested_irq's on failure */ | ||
320 | if (r) | 319 | if (r) |
321 | return r; | 320 | goto err; |
322 | } | 321 | } |
323 | 322 | ||
324 | return 0; | 323 | return 0; |
324 | err: | ||
325 | for (i -= 1; i >= 0; i--) | ||
326 | free_irq(dev->host_msix_entries[i].vector, (void *)dev); | ||
327 | pci_disable_msix(dev->dev); | ||
328 | return r; | ||
325 | } | 329 | } |
326 | 330 | ||
327 | #endif | 331 | #endif |
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 36e258029649..53850177163f 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c | |||
@@ -120,8 +120,10 @@ int kvm_coalesced_mmio_init(struct kvm *kvm) | |||
120 | return ret; | 120 | return ret; |
121 | 121 | ||
122 | out_free_dev: | 122 | out_free_dev: |
123 | kvm->coalesced_mmio_dev = NULL; | ||
123 | kfree(dev); | 124 | kfree(dev); |
124 | out_free_page: | 125 | out_free_page: |
126 | kvm->coalesced_mmio_ring = NULL; | ||
125 | __free_page(page); | 127 | __free_page(page); |
126 | out_err: | 128 | out_err: |
127 | return ret; | 129 | return ret; |
@@ -139,7 +141,7 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, | |||
139 | struct kvm_coalesced_mmio_dev *dev = kvm->coalesced_mmio_dev; | 141 | struct kvm_coalesced_mmio_dev *dev = kvm->coalesced_mmio_dev; |
140 | 142 | ||
141 | if (dev == NULL) | 143 | if (dev == NULL) |
142 | return -EINVAL; | 144 | return -ENXIO; |
143 | 145 | ||
144 | mutex_lock(&kvm->slots_lock); | 146 | mutex_lock(&kvm->slots_lock); |
145 | if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) { | 147 | if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) { |
@@ -162,7 +164,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, | |||
162 | struct kvm_coalesced_mmio_zone *z; | 164 | struct kvm_coalesced_mmio_zone *z; |
163 | 165 | ||
164 | if (dev == NULL) | 166 | if (dev == NULL) |
165 | return -EINVAL; | 167 | return -ENXIO; |
166 | 168 | ||
167 | mutex_lock(&kvm->slots_lock); | 169 | mutex_lock(&kvm->slots_lock); |
168 | 170 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5a0cd194dce0..d6351a34b297 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -341,7 +341,11 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn, | |||
341 | struct mm_struct *mm) | 341 | struct mm_struct *mm) |
342 | { | 342 | { |
343 | struct kvm *kvm = mmu_notifier_to_kvm(mn); | 343 | struct kvm *kvm = mmu_notifier_to_kvm(mn); |
344 | int idx; | ||
345 | |||
346 | idx = srcu_read_lock(&kvm->srcu); | ||
344 | kvm_arch_flush_shadow(kvm); | 347 | kvm_arch_flush_shadow(kvm); |
348 | srcu_read_unlock(&kvm->srcu, idx); | ||
345 | } | 349 | } |
346 | 350 | ||
347 | static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { | 351 | static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { |
@@ -418,9 +422,6 @@ static struct kvm *kvm_create_vm(void) | |||
418 | spin_lock(&kvm_lock); | 422 | spin_lock(&kvm_lock); |
419 | list_add(&kvm->vm_list, &vm_list); | 423 | list_add(&kvm->vm_list, &vm_list); |
420 | spin_unlock(&kvm_lock); | 424 | spin_unlock(&kvm_lock); |
421 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | ||
422 | kvm_coalesced_mmio_init(kvm); | ||
423 | #endif | ||
424 | out: | 425 | out: |
425 | return kvm; | 426 | return kvm; |
426 | 427 | ||
@@ -556,6 +557,10 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
556 | base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; | 557 | base_gfn = mem->guest_phys_addr >> PAGE_SHIFT; |
557 | npages = mem->memory_size >> PAGE_SHIFT; | 558 | npages = mem->memory_size >> PAGE_SHIFT; |
558 | 559 | ||
560 | r = -EINVAL; | ||
561 | if (npages > KVM_MEM_MAX_NR_PAGES) | ||
562 | goto out; | ||
563 | |||
559 | if (!npages) | 564 | if (!npages) |
560 | mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES; | 565 | mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES; |
561 | 566 | ||
@@ -648,7 +653,7 @@ skip_lpage: | |||
648 | 653 | ||
649 | /* Allocate page dirty bitmap if needed */ | 654 | /* Allocate page dirty bitmap if needed */ |
650 | if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) { | 655 | if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) { |
651 | unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8; | 656 | unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new); |
652 | 657 | ||
653 | new.dirty_bitmap = vmalloc(dirty_bytes); | 658 | new.dirty_bitmap = vmalloc(dirty_bytes); |
654 | if (!new.dirty_bitmap) | 659 | if (!new.dirty_bitmap) |
@@ -768,7 +773,7 @@ int kvm_get_dirty_log(struct kvm *kvm, | |||
768 | { | 773 | { |
769 | struct kvm_memory_slot *memslot; | 774 | struct kvm_memory_slot *memslot; |
770 | int r, i; | 775 | int r, i; |
771 | int n; | 776 | unsigned long n; |
772 | unsigned long any = 0; | 777 | unsigned long any = 0; |
773 | 778 | ||
774 | r = -EINVAL; | 779 | r = -EINVAL; |
@@ -780,7 +785,7 @@ int kvm_get_dirty_log(struct kvm *kvm, | |||
780 | if (!memslot->dirty_bitmap) | 785 | if (!memslot->dirty_bitmap) |
781 | goto out; | 786 | goto out; |
782 | 787 | ||
783 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 788 | n = kvm_dirty_bitmap_bytes(memslot); |
784 | 789 | ||
785 | for (i = 0; !any && i < n/sizeof(long); ++i) | 790 | for (i = 0; !any && i < n/sizeof(long); ++i) |
786 | any = memslot->dirty_bitmap[i]; | 791 | any = memslot->dirty_bitmap[i]; |
@@ -910,6 +915,11 @@ int memslot_id(struct kvm *kvm, gfn_t gfn) | |||
910 | return memslot - slots->memslots; | 915 | return memslot - slots->memslots; |
911 | } | 916 | } |
912 | 917 | ||
918 | static unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) | ||
919 | { | ||
920 | return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE; | ||
921 | } | ||
922 | |||
913 | unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | 923 | unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) |
914 | { | 924 | { |
915 | struct kvm_memory_slot *slot; | 925 | struct kvm_memory_slot *slot; |
@@ -918,7 +928,7 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn) | |||
918 | slot = gfn_to_memslot_unaliased(kvm, gfn); | 928 | slot = gfn_to_memslot_unaliased(kvm, gfn); |
919 | if (!slot || slot->flags & KVM_MEMSLOT_INVALID) | 929 | if (!slot || slot->flags & KVM_MEMSLOT_INVALID) |
920 | return bad_hva(); | 930 | return bad_hva(); |
921 | return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); | 931 | return gfn_to_hva_memslot(slot, gfn); |
922 | } | 932 | } |
923 | EXPORT_SYMBOL_GPL(gfn_to_hva); | 933 | EXPORT_SYMBOL_GPL(gfn_to_hva); |
924 | 934 | ||
@@ -968,11 +978,6 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn) | |||
968 | } | 978 | } |
969 | EXPORT_SYMBOL_GPL(gfn_to_pfn); | 979 | EXPORT_SYMBOL_GPL(gfn_to_pfn); |
970 | 980 | ||
971 | static unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) | ||
972 | { | ||
973 | return (slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE); | ||
974 | } | ||
975 | |||
976 | pfn_t gfn_to_pfn_memslot(struct kvm *kvm, | 981 | pfn_t gfn_to_pfn_memslot(struct kvm *kvm, |
977 | struct kvm_memory_slot *slot, gfn_t gfn) | 982 | struct kvm_memory_slot *slot, gfn_t gfn) |
978 | { | 983 | { |
@@ -1602,7 +1607,6 @@ static long kvm_vm_ioctl(struct file *filp, | |||
1602 | r = -EFAULT; | 1607 | r = -EFAULT; |
1603 | if (copy_from_user(&zone, argp, sizeof zone)) | 1608 | if (copy_from_user(&zone, argp, sizeof zone)) |
1604 | goto out; | 1609 | goto out; |
1605 | r = -ENXIO; | ||
1606 | r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone); | 1610 | r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone); |
1607 | if (r) | 1611 | if (r) |
1608 | goto out; | 1612 | goto out; |
@@ -1614,7 +1618,6 @@ static long kvm_vm_ioctl(struct file *filp, | |||
1614 | r = -EFAULT; | 1618 | r = -EFAULT; |
1615 | if (copy_from_user(&zone, argp, sizeof zone)) | 1619 | if (copy_from_user(&zone, argp, sizeof zone)) |
1616 | goto out; | 1620 | goto out; |
1617 | r = -ENXIO; | ||
1618 | r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone); | 1621 | r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone); |
1619 | if (r) | 1622 | if (r) |
1620 | goto out; | 1623 | goto out; |
@@ -1748,12 +1751,19 @@ static struct file_operations kvm_vm_fops = { | |||
1748 | 1751 | ||
1749 | static int kvm_dev_ioctl_create_vm(void) | 1752 | static int kvm_dev_ioctl_create_vm(void) |
1750 | { | 1753 | { |
1751 | int fd; | 1754 | int fd, r; |
1752 | struct kvm *kvm; | 1755 | struct kvm *kvm; |
1753 | 1756 | ||
1754 | kvm = kvm_create_vm(); | 1757 | kvm = kvm_create_vm(); |
1755 | if (IS_ERR(kvm)) | 1758 | if (IS_ERR(kvm)) |
1756 | return PTR_ERR(kvm); | 1759 | return PTR_ERR(kvm); |
1760 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | ||
1761 | r = kvm_coalesced_mmio_init(kvm); | ||
1762 | if (r < 0) { | ||
1763 | kvm_put_kvm(kvm); | ||
1764 | return r; | ||
1765 | } | ||
1766 | #endif | ||
1757 | fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR); | 1767 | fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR); |
1758 | if (fd < 0) | 1768 | if (fd < 0) |
1759 | kvm_put_kvm(kvm); | 1769 | kvm_put_kvm(kvm); |
@@ -2272,7 +2282,6 @@ EXPORT_SYMBOL_GPL(kvm_init); | |||
2272 | 2282 | ||
2273 | void kvm_exit(void) | 2283 | void kvm_exit(void) |
2274 | { | 2284 | { |
2275 | tracepoint_synchronize_unregister(); | ||
2276 | kvm_exit_debug(); | 2285 | kvm_exit_debug(); |
2277 | misc_deregister(&kvm_dev); | 2286 | misc_deregister(&kvm_dev); |
2278 | kmem_cache_destroy(kvm_vcpu_cache); | 2287 | kmem_cache_destroy(kvm_vcpu_cache); |